diff --git a/core/includes/common.inc b/core/includes/common.inc
index 5e9ff1c..ea8fb55 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4838,9 +4838,6 @@ function _drupal_bootstrap_code() {
   require_once DRUPAL_ROOT . '/core/includes/schema.inc';
   require_once DRUPAL_ROOT . '/core/includes/entity.inc';
 
-  // Load all enabled modules
-  drupal_container()->get('module_handler')->loadAll();
-
   // Make sure all stream wrappers are registered.
   file_get_stream_wrappers();
 
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 6bbc5ff..a491853 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1866,6 +1866,7 @@ function _install_module_batch($module, $module_name, &$context) {
   // loaded by drupal_bootstrap in subsequent batch requests, and other
   // modules possibly depending on it can safely perform their installation
   // steps.
+  drupal_container()->get('module_handler')->loadAll();
   module_enable(array($module), FALSE);
   $context['results'][] = $module;
   $context['message'] = st('Installed %module module.', array('%module' => $module_name));
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index ef9f7e2..9a414a3 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -473,6 +473,7 @@ function menu_get_item($path = NULL, $router_item = NULL) {
       // checked for access.
       drupal_alter('menu_get_item', $router_item, $path, $original_map);
 
+      drupal_container()->get('module_handler')->load($router_item['module']);
       $map = _menu_translate($router_item, $original_map);
       $router_item['original_map'] = $original_map;
       if ($map === FALSE) {
@@ -1882,6 +1883,7 @@ function menu_local_tasks($level = 0) {
     $tasks = array();
     $root_path = $router_item['path'];
 
+    drupal_container()->get('module_handler')->load($router_item['module']);
     foreach ($result as $item) {
       _menu_translate($item, $map, TRUE);
       if ($item['tab_parent']) {
@@ -3151,6 +3153,7 @@ function _menu_router_save($menu, $masks) {
       'description_arguments',
       'position',
       'weight',
+      'module',
       'include_file',
     ));
 
@@ -3182,6 +3185,7 @@ function _menu_router_save($menu, $masks) {
       'description_arguments' => ($item['description arguments'] ? serialize($item['description arguments']) : ''),
       'position' => $item['position'],
       'weight' => $item['weight'],
+      'module' => $item['module'],
       'include_file' => $item['include file'],
     ));
 
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 035f282..bbf2063 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -241,6 +241,7 @@ public function build(ContainerBuilder $container) {
       ->addArgument(new Reference('path.alias_manager.cached'))
       ->addTag('event_subscriber');
     $container->register('legacy_request_subscriber', 'Drupal\Core\EventSubscriber\LegacyRequestSubscriber')
+      ->addArgument(new Reference('module_handler'))
       ->addTag('event_subscriber');
     $container->register('legacy_controller_subscriber', 'Drupal\Core\EventSubscriber\LegacyControllerSubscriber')
       ->addTag('event_subscriber');
@@ -325,7 +326,8 @@ protected function registerRouting(ContainerBuilder $container) {
       ->addArgument(new Reference('router.generator'));
 
     $container->register('legacy_generator', 'Drupal\Core\Routing\NullGenerator');
-    $container->register('legacy_url_matcher', 'Drupal\Core\LegacyUrlMatcher');
+    $container->register('legacy_url_matcher', 'Drupal\Core\LegacyUrlMatcher')
+            ->addArgument(new Reference('module_handler'));
     $container->register('legacy_router', 'Symfony\Cmf\Component\Routing\DynamicRouter')
             ->addArgument(new Reference('router.request_context'))
             ->addArgument(new Reference('legacy_url_matcher'))
diff --git a/core/lib/Drupal/Core/EventSubscriber/LegacyRequestSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/LegacyRequestSubscriber.php
index 242f935..b1f28cc 100644
--- a/core/lib/Drupal/Core/EventSubscriber/LegacyRequestSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/LegacyRequestSubscriber.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core\EventSubscriber;
 
+use Drupal\Core\Extension\ModuleHandlerInterface;
+
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -20,6 +22,18 @@
 class LegacyRequestSubscriber implements EventSubscriberInterface {
 
   /**
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Constructor.
+   */
+  function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
    * Initializes the rest of the legacy Drupal subsystems.
    *
    * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
@@ -34,9 +48,13 @@ public function onKernelRequestLegacy(GetResponseEvent $event) {
       // - The theme can have hook_*_alter() implementations affect page
       //   building (e.g., hook_form_alter(), hook_node_view_alter(),
       //   hook_page_alter()), ahead of when rendering starts.
+      // This requires system.module and user.module code to be loaded.
+      foreach (array('system', 'user') as $module) {
+        $this->moduleHandler->load($module);
+      }
       menu_set_custom_theme();
       drupal_theme_initialize();
-      module_invoke_all('init');
+      $this->moduleHandler->invokeAll('init');
 
       // Tell Drupal it is now fully bootstrapped (for the benefit of code that
       // calls drupal_get_bootstrap_phase()), but without having
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index c45c1cd..5b65270 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -451,6 +451,9 @@ protected function getHookInfo() {
     if ($this->hookInfo) {
       return $this->hookInfo;
     }
+    if (!$this->loaded) {
+      $this->loadAll();
+    }
     $this->hookInfo = array();
     // We can't use $this->invokeAll() here or it would cause an infinite
     // loop.
diff --git a/core/lib/Drupal/Core/LegacyUrlMatcher.php b/core/lib/Drupal/Core/LegacyUrlMatcher.php
index 7098b41..68914f3 100644
--- a/core/lib/Drupal/Core/LegacyUrlMatcher.php
+++ b/core/lib/Drupal/Core/LegacyUrlMatcher.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core;
 
+use Drupal\Core\Extension\ModuleHandlerInterface;
+
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
 use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
@@ -19,6 +21,11 @@
 class LegacyUrlMatcher implements RequestMatcherInterface, RequestContextAwareInterface {
 
   /**
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
    * The request context for this matcher.
    *
    * @var Symfony\Component\Routing\RequestContext
@@ -35,7 +42,8 @@ class LegacyUrlMatcher implements RequestMatcherInterface, RequestContextAwareIn
   /**
    * Constructor.
    */
-  public function __construct() {
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
     // We will not actually use this object, but it's needed to conform to
     // the interface.
     $this->context = new RequestContext();
@@ -104,7 +112,7 @@ public function matchRequest(Request $request) {
       $ret = $this->convertDrupalItem($router_item);
       // Stash the router item in the attributes while we're transitioning.
       $ret['drupal_menu_item'] = $router_item;
-
+      $this->moduleHandler->load($router_item['module']);
       // Most legacy controllers (aka page callbacks) are in a separate file,
       // so we have to include that.
       if ($router_item['include_file']) {
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index cfc9a4e..adad9a9 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -950,6 +950,13 @@ function system_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
+      'module' => array(
+        'description' => 'The module providing this menu item.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
       'include_file' => array(
         'description' => 'The file to include for this element, usually the page callback function lives in this file.',
         'type' => 'text',
