diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 8734772..e6345e7 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core;
 
 use Drupal\Core\Cache\ListCacheBinsPass;
+use Drupal\Core\DependencyInjection\Compiler\OptionalDependencyPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
@@ -51,8 +52,7 @@ public function build(ContainerBuilder $container) {
     $container->addCompilerPass(new RegisterRouteFiltersPass());
     // Add a compiler pass for registering event subscribers.
     $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
-    // Add a compiler pass for registering event subscribers.
-    $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
+    $container->addCompilerPass(new OptionalDependencyPass());
     $container->addCompilerPass(new RegisterAccessChecksPass());
     // Add a compiler pass for upcasting of entity route parameters.
     $container->addCompilerPass(new RegisterParamConvertersPass());
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/OptionalDependencyPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/OptionalDependencyPass.php
new file mode 100644
index 0000000..d6a4d97
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/OptionalDependencyPass.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\Compiler\OptionalDependencyPass
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Adds optional dependencies.
+ */
+class OptionalDependencyPass implements CompilerPassInterface {
+
+  public function process(ContainerBuilder $container) {
+    foreach ($container->findTaggedServiceIds('optional_dependency') as $id => $attributes) {
+      $optional_services = array();
+      foreach ($attributes[0] as $key => $reference_id) {
+        if ($reference_id[0] === '@') {
+          $reference_id = substr($reference_id, 1);
+        }
+        if ($container->has($reference_id)) {
+          $optional_services[$key] = new Reference($reference_id);
+        }
+      }
+      if ($optional_services) {
+        $container->getDefinition($id)->addArgument($optional_services);
+      }
+    }
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php b/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php
index 35faa3c..da776ee 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Bundle/BundleTest.php
@@ -40,6 +40,10 @@ function testBundleRegistration() {
     // should show up on the front page.
     $this->drupalGet('');
     $this->assertText(t('The bundle_test event subscriber fired!'), 'The bundle_test event subscriber fired');
+    // Test optional dependencies.
+    $this->assertFalse(drupal_container()->get('bundle_test_class')->hasFormService());
+    module_enable(array('form_test'));
+    $this->assertTrue(drupal_container()->get('bundle_test_class')->hasFormService());
   }
 
   /**
@@ -54,5 +58,4 @@ function testBundleRegistrationDynamic() {
     module_enable(array('bundle_test'));
     $this->assertTrue(drupal_container()->has('bundle_test_class'), 'The bundle_test_class service exists in the DIC.');
   }
-
 }
diff --git a/core/modules/system/tests/modules/bundle_test/bundle_test.services.yml b/core/modules/system/tests/modules/bundle_test/bundle_test.services.yml
index 88b3caf..84fd7b5 100644
--- a/core/modules/system/tests/modules/bundle_test/bundle_test.services.yml
+++ b/core/modules/system/tests/modules/bundle_test/bundle_test.services.yml
@@ -4,6 +4,8 @@ services:
     tags:
       - { name: event_subscriber }
       - { name: needs_destruction }
+# foo: bar is to check that invalid services are not added.
+      - { name: optional_dependency, form_service: '@form_test.form.serviceform', foo: 'bar'}
     arguments: ['@state']
   file.usage:
     class: Drupal\bundle_test\TestFileUsage
diff --git a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php b/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php
index ad711cb..8ebaddf 100644
--- a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php
+++ b/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php
@@ -23,13 +23,23 @@ class TestClass implements EventSubscriberInterface, DestructableInterface {
   protected $state;
 
   /**
+   * A form service, used to test optional dependencies with.
+   *
+   * @var \Drupal\form_test\FormTestServiceObject
+   */
+  protected $formService;
+
+  /**
    * Constructor.
    *
    * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state
    *   The state key value store.
    */
-  public function __construct(KeyValueStoreInterface $state) {
+  public function __construct(KeyValueStoreInterface $state, array $optional_dependencies = array()) {
     $this->state = $state;
+    if (isset($optional_dependencies['form_service'])) {
+      $this->formService = $optional_dependencies['form_service'];
+    }
   }
 
   /**
@@ -56,4 +66,13 @@ static function getSubscribedEvents() {
   public function destruct() {
     $this->state->set('bundle_test.destructed', TRUE);
   }
+
+  /**
+   * @return bool
+   *   TRUE If the form service exists, FALSE otherwise.
+   */
+  public function hasFormService() {
+    return isset($this->formService);
+  }
+
 }
