diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php
index 76a826b1104927a9bb48dded61b7d15f99392082..d953fddff47aaec6d48ad4c86ef40fbbaffb0a4c 100644
--- a/core/lib/Drupal/Core/Routing/RouteBuilder.php
+++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
@@ -112,15 +112,23 @@ public function rebuild() {
       // The top-level 'routes_callback' is a list of methods in controller
       // syntax, see \Drupal\Core\Controller\ControllerResolver. These methods
       // should return a set of \Symfony\Component\Routing\Route objects, either
-      // in an associative array keyed by the route name, or as a new
-      // \Symfony\Component\Routing\RouteCollection, which will be iterated over
-      // and added to the collection for this provider.
+      // in an associative array keyed by the route name, which will be iterated
+      // over and added to the collection for this provider, or as a new
+      // \Symfony\Component\Routing\RouteCollection object, which will be added
+      // to the collection.
       if (isset($routes['route_callbacks'])) {
         foreach ($routes['route_callbacks'] as $route_callback) {
           $callback = $this->controllerResolver->getControllerFromDefinition($route_callback);
           if ($callback_routes = call_user_func($callback)) {
-            foreach ($callback_routes as $name => $callback_route) {
-              $collection->add($name, $callback_route);
+            // If a RouteCollection is returned, add the whole collection.
+            if ($callback_routes instanceof RouteCollection) {
+              $collection->addCollection($callback_routes);
+            }
+            // Otherwise, add each Route object individually.
+            else {
+              foreach ($callback_routes as $name => $callback_route) {
+                $collection->add($name, $callback_route);
+              }
             }
           }
         }