diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index db54f91..7ffe9f0 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -16,7 +16,7 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
 use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass;
-use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
+use Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass;
 use Drupal\Core\Plugin\PluginManagerPass;
@@ -59,7 +59,7 @@ public function register(ContainerBuilder $container) {
     $container->addCompilerPass(new RegisterStreamWrappersPass());
 
     // Add a compiler pass for registering event subscribers.
-    $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
+    $container->addCompilerPass(new RegisterEventListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
 
     $container->addCompilerPass(new RegisterAccessChecksPass());
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventListenersPass.php
similarity index 54%
rename from core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php
rename to core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventListenersPass.php
index 33b2683..d9e8242 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventListenersPass.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass.
+ * Contains \Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass.
  */
 
 namespace Drupal\Core\DependencyInjection\Compiler;
@@ -10,7 +10,10 @@
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
 
-class RegisterKernelListenersPass implements CompilerPassInterface {
+/**
+ * Registers listeners for all services tagged with 'event_subscriber'.
+ */
+class RegisterEventListenersPass implements CompilerPassInterface {
   public function process(ContainerBuilder $container) {
     if (!$container->hasDefinition('event_dispatcher')) {
       return;
@@ -19,8 +22,43 @@ public function process(ContainerBuilder $container) {
     $definition = $container->getDefinition('event_dispatcher');
 
     $event_subscriber_info = [];
-    foreach ($container->findTaggedServiceIds('event_subscriber') as $id => $attributes) {
 
+    $module_parameter = $container->hasParameter('container.modules') ? $container->getParameter('container.modules') : [];
+
+    // First collect all tagged services in order to sort them by module weight
+    // and class name.
+
+    $weights = [];
+    // First figure out all module weights.
+    $ids = array_keys($container->findTaggedServiceIds('event_subscriber'));
+    $id_class_map = [];
+    foreach ($ids as $id) {
+      $class = $container->getDefinition($id)->getClass();
+      $id_class_map[$id] = $class;
+
+      list($drupal, $provider, $rest) = explode('\\', $class, 3);
+
+      if ($drupal == 'Drupal' && isset($module_parameter[$provider]['weight'])) {
+        $weight = $module_parameter[$provider]['weight'];
+      }
+      else {
+        $weight = 0;
+      }
+      $weights[$id] = $weight;
+    }
+
+    // Sort the IDs first by module weight, than by full classname. Using the
+    // full classname takes into account the module name automatically.
+    usort($ids, function($a, $b) use ($weights, $id_class_map) {
+      if ($weights[$a] !== $weights[$b]) {
+        return $weights[$a] < $weights[$b] ? -1 : 1;
+      }
+      else {
+        return $id_class_map[$a] < $id_class_map[$b] ? -1 : 1;
+      }
+    });
+
+    foreach ($ids as $id) {
       // We must assume that the class value has been correctly filled, even if the service is created by a factory
       $class = $container->getDefinition($id)->getClass();
 
@@ -31,6 +69,7 @@ public function process(ContainerBuilder $container) {
       }
 
       // Get all subscribed events.
+      // @todo Implement sorting by module weight and class name.
       foreach ($class::getSubscribedEvents() as $event_name => $params) {
         if (is_string($params)) {
           $priority = 0;
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index c014e4a..fe3a55e 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -1193,6 +1193,7 @@ protected function getModulesParameter() {
           'type' => $data->getType(),
           'pathname' => $data->getPathname(),
           'filename' => $data->getExtensionFilename(),
+          'weight' => $weight,
         );
       }
     }
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/RegisterEventListenersPassTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/RegisterEventListenersPassTest.php
new file mode 100644
index 0000000..a9ef0d4
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/RegisterEventListenersPassTest.php
@@ -0,0 +1,202 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\DependencyInjection\Compiler\RegisterEventListenersPassTest.
+ */
+
+namespace Drupal\Tests\Core\DependencyInjection\Compiler {
+
+use Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * @coversDefaultClass \Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass
+ * @group DependencyInjection
+ */
+class RegisterEventListenersPassTest extends UnitTestCase {
+
+  /**
+   * The tested compiler pass.
+   *
+   * @var \Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass
+   */
+  protected $pass;
+
+  protected function setUp() {
+    parent::setUp();
+
+    $this->pass = new RegisterEventListenersPass();
+  }
+
+  /**
+   * Tests process with a service with an invalid interface.
+   *
+   * @expectedException \InvalidArgumentException
+   */
+  public function testProcessWithWrongInterface() {
+    $builder = new ContainerBuilder();
+    $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service', 'Drupal\Tests\Core\DependencyInjection\Compiler\TestServiceWithoutInterface')
+      ->addTag('event_subscriber');
+    $this->pass->process($builder);
+  }
+
+  /**
+   * Tests process with a single subscriber.
+   */
+  public function testProcessWithSubscriber() {
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service', 'Drupal\register_event_listener_pass_test_module\TestService1')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([[0 => ['service' => ['test_service', 'onExample']]]], $listeners['example']);
+  }
+
+  /**
+   * Tests process with multiple listeners and priority.
+   */
+  public function testProcessWithSubscriberWithPriorities() {
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service', 'Drupal\register_event_listener_pass_test_module\TestService2')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([
+      10 => [['service' => ['test_service', 'onExample2']]],
+      0 => [['service' => ['test_service', 'onExample1']]]
+    ], $listeners['example']);
+  }
+
+  /**
+   * Tests process with multiple subscribers in different modules and same prio.
+   *
+   * We register the subscribers ascending in the module name.
+   */
+  public function testProcessWithMultipleSubscribersWithModuleWeightAndSamePriorities() {
+    // @FIXME Introduce the weight of the modules.
+
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+    $builder->setParameter('container.modules', [
+      'register_event_listener_pass_test_nodule' => [
+        'weight' => -10,
+      ],
+      'register_event_listener_pass_test_module' => [
+        'weight' => 0,
+      ],
+    ]);
+
+    $builder->register('test_service_0', 'Drupal\register_event_listener_pass_test_module\TestService1')
+      ->addTag('event_subscriber');
+    $builder->register('test_service_1', 'Drupal\register_event_listener_pass_test_nodule\TestService1')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([
+      0 => [
+        ['service' => ['test_service_1', 'onExample']],
+        ['service' => ['test_service_0', 'onExample']],
+      ],
+    ], $listeners['example']);
+  }
+
+  /**
+   * Tests process with multiple subscribers, same module and same priorities.
+   *
+   * The idea is that we sort the listeners by class name as well, so
+   * setup the later classname first in the container.
+   */
+  public function testProcessWithMultipleSubscribersSameModuleAndSamePriorities() {
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service_0', 'Drupal\register_event_listener_pass_test_module\TestService2')
+      ->addTag('event_subscriber');
+    $builder->register('test_service_1', 'Drupal\register_event_listener_pass_test_module\TestService1')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([
+      10 => [['service' => ['test_service_0', 'onExample2']]],
+      0 => [
+        ['service' => ['test_service_1', 'onExample']],
+        ['service' => ['test_service_0', 'onExample1']]
+      ],
+    ], $listeners['example']);
+  }
+
+}
+
+class TestServiceWithoutInterface {
+
+}
+
+}
+
+namespace Drupal\register_event_listener_pass_test_module {
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class TestService1 implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events['example'] = 'onExample';
+
+    return $events;
+  }
+
+}
+
+class TestService2 implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events['example'][] = ['onExample1'];
+    $events['example'][] = ['onExample2', 10];
+
+    return $events;
+  }
+
+}
+}
+
+namespace Drupal\register_event_listener_pass_test_nodule {
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class TestService1 implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events['example'] = 'onExample';
+
+    return $events;
+  }
+}
+
+}
+
