diff --git a/core/lib/Drupal/Core/Config/ConfigEvents.php b/core/lib/Drupal/Core/Config/ConfigEvents.php
index 0b0bb3a..8f61193 100644
--- a/core/lib/Drupal/Core/Config/ConfigEvents.php
+++ b/core/lib/Drupal/Core/Config/ConfigEvents.php
@@ -35,13 +35,6 @@
   const RENAME = 'config.rename';
 
   /**
-   * Name of event fired when collecting overrides for configuration objects.
-   *
-   * @see \Drupal\Core\Config\ConfigFactory::loadModuleOverrides().
-   */
-  const MODULE_OVERRIDES = 'config.module.overrides';
-
-  /**
    * Name of event fired when validating in the configuration import process.
    *
    * @see \Drupal\Core\Config\ConfigImporter::validate().
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
index 3d26c78..289141d 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactory.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageDefault;
 use Symfony\Component\EventDispatcher\EventDispatcher;
+use Drupal\Component\Utility\NestedArray;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
@@ -71,6 +72,20 @@ class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface
   protected $typedConfigManager;
 
   /**
+   * An array of config factory override objects grouped by priority.
+   *
+   * @var array
+   */
+  protected $configFactoryOverrides = array();
+
+  /**
+   * An array of sorted config factory override objects.
+   *
+   * @var array|\Drupal\Core\Config\ConfigFactoryOverrideInterface[]
+   */
+  protected $sortedConfigFactoryOverrides;
+
+  /**
    * Constructs the Config factory.
    *
    * @param \Drupal\Core\Config\StorageInterface $storage
@@ -222,9 +237,13 @@ public function loadMultiple(array $names) {
    *   An array of overrides keyed by the configuration object name.
    */
   protected function loadModuleOverrides(array $names) {
-    $configOverridesEvent = new ConfigModuleOverridesEvent($names, $this->language);
-    $this->eventDispatcher->dispatch(ConfigEvents::MODULE_OVERRIDES, $configOverridesEvent);
-    return $configOverridesEvent->getOverrides();
+    $overrides = array();
+    foreach ($this->getSortedConfigFactoryOverrides() as $override) {
+      // Existing overrides take precedence since these will have been added
+      // by events with a higher priority.
+      $overrides = NestedArray::mergeDeepArray(array($override->loadOverrides($names), $overrides), TRUE);
+    }
+    return $overrides;
   }
 
   /**
@@ -392,4 +411,30 @@ static function getSubscribedEvents() {
     return $events;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function addOverride(ConfigFactoryOverrideInterface $config_factory_override, $priority) {
+    $this->configFactoryOverrides[$priority][] = $config_factory_override;
+    // Force the overrides to be re-sorted.
+    $this->sortedConfigFactoryOverrides = NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSortedConfigFactoryOverrides() {
+    if (!isset($this->sortedConfigFactoryOverrides)) {
+      // Sort the override objects according to priority.
+      krsort($this->configFactoryOverrides);
+      // Merge nested override objects from $this->configFactoryOverrides into
+      // $this->sortedConfigFactoryOverrides.
+      $this->sortedConfigFactoryOverrides = array();
+      foreach ($this->configFactoryOverrides as $overrides) {
+        $this->sortedConfigFactoryOverrides = array_merge($this->sortedConfigFactoryOverrides, $overrides);
+      }
+    }
+    return $this->sortedConfigFactoryOverrides;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php
index e836a2b..7380bb7 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactoryInterface.php
@@ -191,4 +191,22 @@ public function getLanguageConfigName($langcode, $name);
    */
   public function listAll($prefix = '');
 
+  /**
+   * Adds config factory overrides.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryOverrideInterface $config_factory_override
+   *   The config factory override to add.
+   * @param int $priority
+   *   Priority of the config factory override.
+   */
+  public function addOverride(ConfigFactoryOverrideInterface $config_factory_override, $priority);
+
+  /**
+   * Returns the sorted array of config factory override objects.
+   *
+   * @return array|\Drupal\Core\Config\ConfigFactoryOverrideInterface[]
+   *   An array of config factory override objects.
+   */
+  public function getSortedConfigFactoryOverrides();
+
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php
new file mode 100644
index 0000000..1ba5a41
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Config\ConfigFactoryOverrideInterface.
+ */
+
+namespace Drupal\Core\Config;
+
+/**
+ * Defines the interface for a configuration factory override object.
+ */
+interface ConfigFactoryOverrideInterface {
+
+  /**
+   * @param array $names
+   *   A list of configuration names that are being loaded.
+   *
+   * @return array
+   *   An array keyed by configuration name of override data. Override data
+   *   contains a nested array structure of overrides.
+   */
+  public function loadOverrides($names);
+
+}
diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryOverridePass.php b/core/lib/Drupal/Core/Config/ConfigFactoryOverridePass.php
new file mode 100644
index 0000000..beae669
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverridePass.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Config\ConfigFactoryOverridePass.
+ */
+
+namespace Drupal\Core\Config;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Adds services to the config factory service.
+ *
+ * @see \Drupal\Core\Config\ConfigFactory
+ * @see \Drupal\Core\Config\ConfigFactoryOverrideInterface
+ */
+class ConfigFactoryOverridePass implements CompilerPassInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function process(ContainerBuilder $container) {
+    $manager = $container->getDefinition('config.factory');
+    foreach ($container->findTaggedServiceIds('config.factory.override') as $id => $attributes) {
+      $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
+      $manager->addMethodCall('addOverride', array(new Reference($id), $priority));
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 847960c..5c3526f 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core;
 
 use Drupal\Core\Cache\ListCacheBinsPass;
+use Drupal\Core\Config\ConfigFactoryOverridePass;
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
@@ -78,6 +79,9 @@ public function register(ContainerBuilder $container) {
     // Add the compiler pass that will process the tagged theme negotiator
     // service.
     $container->addCompilerPass(new ThemeNegotiatorPass());
+    // Add the compiler pass that will process the tagged config factory
+    // override services.
+    $container->addCompilerPass(new ConfigFactoryOverridePass());
     // Add the compiler pass that will process tagged authentication services.
     $container->addCompilerPass(new RegisterAuthenticationPass());
     // Register Twig extensions.
diff --git a/core/modules/config/tests/config_override/config_override.services.yml b/core/modules/config/tests/config_override/config_override.services.yml
index 586ce49..5272a84 100644
--- a/core/modules/config/tests/config_override/config_override.services.yml
+++ b/core/modules/config/tests/config_override/config_override.services.yml
@@ -1,9 +1,9 @@
 services:
-  config_override_config_subscriber:
-    class: Drupal\config_override\EventSubscriber\ConfigModuleOverrideSubscriber
+  config_override.overrider:
+    class: Drupal\config_override\ConfigOverrider
     tags:
-      - { name: event_subscriber }
-  config_override_low_priority_config_subscriber:
-    class: Drupal\config_override\EventSubscriber\ConfigModuleLowPriorityOverrideSubscriber
+      - { name: config.factory.override}
+  config_override.low_priority_overrider:
+    class: Drupal\config_override\ConfigOverriderLowPriority
     tags:
-      - { name: event_subscriber }
+      - { name: config.factory.override, priority: -100 }
diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php
new file mode 100644
index 0000000..7ed4bf6
--- /dev/null
+++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverrider.php
@@ -0,0 +1,37 @@
+<?Php
+
+/**
+ * @file
+ * Contains \Drupal\config_override\ConfigOverrider.
+ */
+
+namespace Drupal\config_override;
+
+use Drupal\Core\Config\ConfigEvents;
+use Drupal\Core\Config\ConfigFactoryOverrideInterface;
+use Drupal\Core\Config\ConfigModuleOverridesEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Tests module overrides for configuration.
+ */
+class ConfigOverrider implements ConfigFactoryOverrideInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function loadOverrides($names) {
+    $overrides = array();
+    if (!empty($GLOBALS['config_test_run_module_overrides'])) {
+      if (in_array('system.site', $names)) {
+        $overrides = $overrides + array('system.site' => array('name' => 'ZOMG overridden site name'));
+      }
+      if (in_array('config_override.new', $names)) {
+        $overrides = $overrides + array('config_override.new' => array('module' => 'override'));
+      }
+    }
+    return $overrides;
+  }
+
+}
+
diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php
new file mode 100644
index 0000000..6bf8ee1
--- /dev/null
+++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/ConfigOverriderLowPriority.php
@@ -0,0 +1,38 @@
+<?Php
+
+/**
+ * @file
+ * Contains \Drupal\config_override\ConfigOverriderLowPriority.
+ */
+
+namespace Drupal\config_override;
+
+use Drupal\Core\Config\ConfigFactoryOverrideInterface;
+
+/**
+ * Tests module overrides for configuration.
+ */
+class ConfigOverriderLowPriority implements ConfigFactoryOverrideInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function loadOverrides($names) {
+    $overrides = array();
+    if (!empty($GLOBALS['config_test_run_module_overrides'])) {
+      if (in_array('system.site', $names)) {
+        $overrides = array('system.site' =>
+          array(
+            // This override should apply because it is not overridden by the
+            // higher priority listener.
+            'name' => 'Should not apply because of higher priority listener',
+            'slogan' => 'Yay for overrides!',
+          )
+        );
+      }
+    }
+    return $overrides;
+  }
+
+}
+
diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleLowPriorityOverrideSubscriber.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleLowPriorityOverrideSubscriber.php
deleted file mode 100644
index fd7e26c..0000000
--- a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleLowPriorityOverrideSubscriber.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?Php
-
-/**
- * @file
- * Contains \Drupal\config_override\EventSubscriber\ConfigModuleLowPriorityOverrideSubscriber.
- */
-
-namespace Drupal\config_override\EventSubscriber;
-
-use Drupal\Core\Config\ConfigEvents;
-use Drupal\Core\Config\ConfigModuleOverridesEvent;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-
-/**
- * Tests module overrides for configuration.
- */
-class ConfigModuleLowPriorityOverrideSubscriber implements EventSubscriberInterface {
-
-  public function onConfigModuleOverride(ConfigModuleOverridesEvent $event) {
-    if (!empty($GLOBALS['config_test_run_module_overrides'])) {
-      $names = $event->getNames();
-      if (in_array('system.site', $names)) {
-        $event->setOverride('system.site', array(
-          'name' => 'Should not apply because of higher priority listener',
-          // This override should apply because it is not overridden by the
-          // higher priority listener.
-          'slogan' => 'Yay for overrides!',
-        ));
-      }
-    }
-  }
-
-  /**
-   * Registers the methods in this class that should be listeners.
-   *
-   * @return array
-   *   An array of event listener definitions.
-   */
-  static function getSubscribedEvents() {
-    $events[ConfigEvents::MODULE_OVERRIDES][] = array('onConfigModuleOverride', 35);
-    return $events;
-  }
-}
-
diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleOverrideSubscriber.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleOverrideSubscriber.php
deleted file mode 100644
index e168111..0000000
--- a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleOverrideSubscriber.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?Php
-
-/**
- * @file
- * Contains \Drupal\config_override\EventSubscriber\ConfigModuleOverrideSubscriber.
- */
-
-namespace Drupal\config_override\EventSubscriber;
-
-use Drupal\Core\Config\ConfigEvents;
-use Drupal\Core\Config\ConfigModuleOverridesEvent;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-
-/**
- * Tests module overrides for configuration.
- */
-class ConfigModuleOverrideSubscriber implements EventSubscriberInterface {
-
-  public function onConfigModuleOverride(ConfigModuleOverridesEvent $event) {
-    if (!empty($GLOBALS['config_test_run_module_overrides'])) {
-      $names = $event->getNames();
-      if (in_array('system.site', $names)) {
-        $event->setOverride('system.site', array('name' => 'ZOMG overridden site name'));
-      }
-      if (in_array('config_override.new', $names)) {
-        $event->setOverride('config_override.new', array('module' => 'override'));
-      }
-    }
-  }
-
-  /**
-   * Registers the methods in this class that should be listeners.
-   *
-   * @return array
-   *   An array of event listener definitions.
-   */
-  static function getSubscribedEvents() {
-    $events[ConfigEvents::MODULE_OVERRIDES][] = array('onConfigModuleOverride', 40);
-    return $events;
-  }
-}
-
