diff --git a/guix/profiles.scm b/guix/profiles.scm
index cd3b21e3905f9289de2742b5e5f1d9c327fed4f4..f5e5cc33d641cc91fe4e62a5948f34694a68d41c 100644
--- a/guix/profiles.scm
+++ b/guix/profiles.scm
@@ -92,6 +92,7 @@ (define-module (guix profiles)
             manifest-pattern-version
             manifest-pattern-output
 
+            concatenate-manifests
             manifest-remove
             manifest-add
             manifest-lookup
@@ -515,6 +516,10 @@ (define (read-manifest port)
   "Return the packages listed in MANIFEST."
   (sexp->manifest (read port)))
 
+(define (concatenate-manifests lst)
+  "Concatenate the manifests listed in LST and return the resulting manifest."
+  (manifest (append-map manifest-entries lst)))
+
 (define (entry-predicate pattern)
   "Return a procedure that returns #t when passed a manifest entry that
 matches NAME/OUTPUT/VERSION.  OUTPUT and VERSION may be #f, in which case they
diff --git a/tests/profiles.scm b/tests/profiles.scm
index a4e28672b54ce77471bf168e83ea8722e4c3d72e..21c912a532be1137a0701cf634be82055071a9b2 100644
--- a/tests/profiles.scm
+++ b/tests/profiles.scm
@@ -113,6 +113,11 @@ (define glibc
       (manifest-matching-entries m (list p))
       #f)))
 
+(test-equal "concatenate-manifests"
+  (manifest (list guile-2.0.9 glibc))
+  (concatenate-manifests (list (manifest (list guile-2.0.9))
+                               (manifest (list glibc)))))
+
 (test-assert "manifest-remove"
   (let* ((m0 (manifest (list guile-2.0.9 guile-2.0.9:debug)))
          (m1 (manifest-remove m0