diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm
index f94a1e7087..326ab92365 100644
--- a/guix/import/hackage.scm
+++ b/guix/import/hackage.scm
@@ -227,10 +227,13 @@ package being processed and is used to filter references to itself."
           dependencies))
 
 (define* (hackage-module->sexp cabal cabal-hash
-                               #:key (include-test-dependencies? #t))
+                               #:key
+                               (include-test-dependencies? #t)
+                               (source #f))
   "Return the `package' S-expression for a Cabal package.  CABAL is the
-representation of a Cabal file as produced by 'read-cabal'.  CABAL-HASH is
-the hash of the Cabal file."
+representation of a Cabal file as produced by 'read-cabal'.  CABAL-HASH is the
+hash of the Cabal file.  If SOURCE is specified, it will be used as the source
+for the package."
 
   (define name
     (cabal-package-name cabal))
@@ -294,20 +297,24 @@ the hash of the Cabal file."
       (() '())
       (args `((arguments (,'quasiquote ,args))))))
 
-  (let ((tarball (with-store store
-                   (download-to-store store source-url))))
+  (let ((tarball (if source
+                     #f
+                     (with-store store
+                       (download-to-store store source-url)))))
     (values
      `(package
         (name ,(hackage-name->package-name name))
         (version ,version)
-        (source (origin
-                  (method url-fetch)
-                  (uri (string-append ,@(factorize-uri source-url version)))
-                  (sha256
-                   (base32
-                    ,(if tarball
-                         (bytevector->nix-base32-string (file-sha256 tarball))
-                         "failed to download tar archive")))))
+        (source ,(if source
+                     source
+                     `(origin
+                        (method url-fetch)
+                        (uri (string-append ,@(factorize-uri source-url version)))
+                        (sha256
+                         (base32
+                          ,(if tarball
+                               (bytevector->nix-base32-string (file-sha256 tarball))
+                               "failed to download tar archive"))))))
         (build-system haskell-build-system)
         ,@(maybe-inputs 'inputs dependencies)
         ,@(maybe-inputs 'native-inputs native-dependencies)
@@ -321,10 +328,12 @@ the hash of the Cabal file."
 (define* (hackage->guix-package package-name #:key
                                 (include-test-dependencies? #t)
                                 (port #f)
+                                (source #f)
                                 (cabal-environment '()))
   "Fetch the Cabal file for PACKAGE-NAME from hackage.haskell.org, or, if the
-called with keyword parameter PORT, from PORT.  Return the `package'
-S-expression corresponding to that package, or #f on failure.
+called with keyword parameter PORT, from PORT.  If SOURCE is specified, use it
+as the source for the package instead of trying to fetch a tarball.  Return
+the `package' S-expression corresponding to that package, or #f on failure.
 CABAL-ENVIRONMENT is an alist defining the environment in which the Cabal
 conditionals are evaluated.  The accepted keys are: \"os\", \"arch\", \"impl\"
 and the name of a flag.  The value associated with a flag has to be either the
@@ -338,7 +347,9 @@ respectively."
                     (hackage-fetch-and-hash package-name))))
     (and=> cabal-meta (compose (cut hackage-module->sexp <> cabal-hash
                                     #:include-test-dependencies?
-                                    include-test-dependencies?)
+                                    include-test-dependencies?
+                                    #:source
+                                    source)
                                (cut eval-cabal <> cabal-environment)))))
 
 (define hackage->guix-package/m                   ;memoized variant
diff --git a/tests/hackage.scm b/tests/hackage.scm
index 66a13d9881..54590dcece 100644
--- a/tests/hackage.scm
+++ b/tests/hackage.scm
@@ -22,6 +22,7 @@
   #:use-module (guix import cabal)
   #:use-module (guix import hackage)
   #:use-module (guix tests)
+  #:use-module (guix gexp)
   #:use-module (srfi srfi-64)
   #:use-module (ice-9 match))
 
@@ -186,9 +187,28 @@ library
     ('description (? string?))
     ('license 'license:bsd-3)))
 
-(define* (eval-test-with-cabal test-cabal matcher #:key (cabal-environment '()))
+(define-package-matcher match-ghc-foo-local-source
+  ('package
+    ('name "ghc-foo")
+    ('version "1.0.0")
+    ('source
+     (? file-like?))
+    ('build-system 'haskell-build-system)
+    ('inputs
+     ('quasiquote
+      (("ghc-http" ('unquote 'ghc-http)))))
+    ('home-page "http://test.org")
+    ('synopsis (? string?))
+    ('description (? string?))
+    ('license 'license:bsd-3)))
+
+(define* (eval-test-with-cabal test-cabal matcher
+                               #:key (cabal-environment '()) (source #f))
   (define port (open-input-string test-cabal))
-  (matcher (hackage->guix-package "foo" #:port port #:cabal-environment cabal-environment)))
+  (matcher (hackage->guix-package "foo"
+                                  #:port port
+                                  #:cabal-environment cabal-environment
+                                  #:source source)))
 
 (test-assert "hackage->guix-package test 1"
   (eval-test-with-cabal test-cabal-1 match-ghc-foo))
@@ -208,6 +228,10 @@ library
   (eval-test-with-cabal test-cabal-5 match-ghc-foo
                         #:cabal-environment '(("impl" . "ghc-7.8"))))
 
+(test-assert "hackage->guix-package local source"
+  (eval-test-with-cabal test-cabal-1 match-ghc-foo-local-source
+                        #:source (plain-file "dummy source" "source")))
+
 (define-package-matcher match-ghc-foo-6
   ('package
     ('name "ghc-foo")
