diff --git a/core/core.services.yml b/core/core.services.yml
index 53a2725..bcae2d9 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1281,15 +1281,15 @@ services:
     class: Drupal\Core\Asset\AssetDumper
   library.discovery:
     class: Drupal\Core\Asset\LibraryDiscovery
-    arguments: ['@library.discovery.collector', '@module_handler']
+    arguments: ['@library.discovery.collector', '@cache_tags.invalidator', '@module_handler', '@theme.manager']
   library.discovery.collector:
     class: Drupal\Core\Asset\LibraryDiscoveryCollector
-    arguments: ['@cache.discovery', '@lock', '@library.discovery.parser']
+    arguments: ['@cache.discovery', '@lock', '@library.discovery.parser', '@theme.manager']
     tags:
       - { name: needs_destruction }
   library.discovery.parser:
     class: Drupal\Core\Asset\LibraryDiscoveryParser
-    arguments: ['@app.root', '@module_handler']
+    arguments: ['@app.root', '@module_handler', '@theme.manager']
   library.dependency_resolver:
     class: Drupal\Core\Asset\LibraryDependencyResolver
     arguments: ['@library.discovery']
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscovery.php b/core/lib/Drupal/Core/Asset/LibraryDiscovery.php
index c79674a..71926ee 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscovery.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscovery.php
@@ -8,7 +8,9 @@
 namespace Drupal\Core\Asset;
 
 use Drupal\Core\Cache\CacheCollectorInterface;
+use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Theme\ThemeManagerInterface;
 
 /**
  * Discovers available asset libraries in Drupal.
@@ -23,6 +25,13 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
   protected $collector;
 
   /**
+   * The cache tag invalidator.
+   *
+   * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface
+   */
+  protected $cacheTagInvalidator;
+
+  /**
    * The module handler.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface
@@ -30,6 +39,13 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
   protected $moduleHandler;
 
   /**
+   * The theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface
+   */
+  protected $themeManager;
+
+  /**
    * The final library definitions, statically cached.
    *
    * hook_library_info_alter() and hook_js_settings_alter() allows modules
@@ -44,12 +60,18 @@ class LibraryDiscovery implements LibraryDiscoveryInterface {
    *
    * @param \Drupal\Core\Cache\CacheCollectorInterface $library_discovery_collector
    *   The library discovery cache collector.
+   * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tag_invalidator
+   *   The cache tag invalidator.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
+   *   The theme manager.
    */
-  public function __construct(CacheCollectorInterface $library_discovery_collector, ModuleHandlerInterface $module_handler) {
+  public function __construct(CacheCollectorInterface $library_discovery_collector, CacheTagsInvalidatorInterface $cache_tag_invalidator, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) {
     $this->collector = $library_discovery_collector;
+    $this->cacheTagInvalidator = $cache_tag_invalidator;
     $this->moduleHandler = $module_handler;
+    $this->themeManager = $theme_manager;
   }
 
   /**
@@ -64,6 +86,7 @@ public function getLibrariesByExtension($extension) {
         // specific data for this library; e.g., localization.
         $library_name = "$extension/$name";
         $this->moduleHandler->alter('library', $definition, $library_name);
+        $this->themeManager->alter('library', $definition, $library_name);
         $this->libraryDefinitions[$extension][$name] = $definition;
       }
     }
@@ -83,7 +106,7 @@ public function getLibraryByName($extension, $name) {
    * {@inheritdoc}
    */
   public function clearCachedDefinitions() {
-    $this->collector->clear();
+    $this->cacheTagInvalidator->invalidateTags(['library_info']);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php
index dfac4fa..91d1248 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Cache\CacheCollector;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Lock\LockBackendInterface;
+use Drupal\Core\Theme\ThemeManagerInterface;
 
 /**
  * A CacheCollector implementation for building library extension info.
@@ -17,13 +18,6 @@
 class LibraryDiscoveryCollector extends CacheCollector {
 
   /**
-   * The cache key.
-   *
-   * @var string
-   */
-  protected $cacheKey = 'library_info';
-
-  /**
    * The cache backend.
    *
    * @var \Drupal\Core\Cache\CacheBackendInterface
@@ -45,6 +39,13 @@ class LibraryDiscoveryCollector extends CacheCollector {
   protected $discoveryParser;
 
   /**
+   * The theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface
+   */
+  protected $themeManager;
+
+  /**
    * Constructs a CacheCollector object.
    *
    * @param string $cid
@@ -56,8 +57,10 @@ class LibraryDiscoveryCollector extends CacheCollector {
    * @param \Drupal\Core\Asset\LibraryDiscoveryParser $discovery_parser
    *   The library discovery parser.
    */
-  public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, LibraryDiscoveryParser $discovery_parser) {
-    parent::__construct($this->cacheKey, $cache, $lock, array($this->cacheKey));
+  public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, LibraryDiscoveryParser $discovery_parser, ThemeManagerInterface $theme_manager) {
+    $this->themeManager = $theme_manager;
+    $cid = 'library_info:' . $this->themeManager->getActiveTheme()->getName();
+    parent::__construct($cid, $cache, $lock, ['library_info']);
 
     $this->discoveryParser = $discovery_parser;
   }
@@ -71,5 +74,4 @@ protected function resolveCacheMiss($key) {
 
     return $this->storage[$key];
   }
-
 }
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 26ba97a..7e9ba06 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Asset\Exception\InvalidLibraryFileException;
 use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Theme\ThemeManagerInterface;
 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
 use Drupal\Component\Serialization\Yaml;
 use Drupal\Component\Utility\NestedArray;
@@ -28,6 +29,13 @@ class LibraryDiscoveryParser {
   protected $moduleHandler;
 
   /**
+   * The theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface
+   */
+  protected $themeManager;
+
+  /**
    * The app root.
    *
    * @var string
@@ -42,9 +50,10 @@ class LibraryDiscoveryParser {
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
    */
-  public function __construct($root, ModuleHandlerInterface $module_handler) {
+  public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) {
     $this->root = $root;
     $this->moduleHandler = $module_handler;
+    $this->themeManager = $theme_manager;
   }
 
   /**
@@ -241,6 +250,7 @@ protected function parseLibraryInfo($extension, $path) {
 
     // Allow modules to alter the module's registered libraries.
     $this->moduleHandler->alter('library_info', $libraries, $extension);
+    $this->themeManager->alter('library_info', $libraries, $extension);
 
     return $libraries;
   }
diff --git a/core/modules/system/src/Tests/Asset/LibraryDiscoveryIntegrationTest.php b/core/modules/system/src/Tests/Asset/LibraryDiscoveryIntegrationTest.php
new file mode 100644
index 0000000..45d3b44
--- /dev/null
+++ b/core/modules/system/src/Tests/Asset/LibraryDiscoveryIntegrationTest.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Asset\LibraryDiscoveryIntegrationTest.
+ */
+
+namespace Drupal\system\Tests\Asset;
+
+use Drupal\simpletest\KernelTestBase;
+
+/**
+ * Tests the element info.
+ *
+ * @group Render
+ */
+class LibraryDiscoveryIntegrationTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->container->get('theme_handler')->install(['test_theme', 'classy']);
+  }
+
+  /**
+   * Ensures that the element info can be altered by themes.
+   */
+  public function testElementInfoByTheme() {
+    /** @var \Drupal\Core\Theme\ThemeInitializationInterface $theme_initializer */
+    $theme_initializer = $this->container->get('theme.initialization');
+
+    /** @var \Drupal\Core\Theme\ThemeManagerInterface $theme_manager */
+    $theme_manager = $this->container->get('theme.manager');
+
+    $theme_manager->setActiveTheme($theme_initializer->getActiveThemeByName('test_theme'));
+    /** @var \Drupal\Core\Render\ElementInfoManagerInterface $element_info */
+    $library_discovery = $this->container->get('library.discovery');
+    $this->assertTrue($library_discovery->getLibraryByName('test_theme', 'kitten'));
+  }
+
+}
diff --git a/core/modules/system/tests/themes/test_theme/test_theme.theme b/core/modules/system/tests/themes/test_theme/test_theme.theme
index 951fd58..9350755 100644
--- a/core/modules/system/tests/themes/test_theme/test_theme.theme
+++ b/core/modules/system/tests/themes/test_theme/test_theme.theme
@@ -29,6 +29,10 @@ function test_theme_element_info_alter(&$info) {
   }
 }
 
+function test_theme_library_info_alter(&$libraries) {
+  $libraries['kitten']['js'][] = 'kittens.js';
+}
+
 /**
  * Tests a theme implementing an alter hook.
  *
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryCollectorTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryCollectorTest.php
index 5993669..e0ac986 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryCollectorTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryCollectorTest.php
@@ -41,6 +41,13 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
   protected $libraryDiscoveryCollector;
 
   /**
+   * The mocked theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $themeManager;
+
+  /**
    * Test library data.
    *
    * @var array
@@ -56,17 +63,21 @@ class LibraryDiscoveryCollectorTest extends UnitTestCase {
     ),
   );
 
+  protected $activeTheme;
+
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
     $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
+    $this->themeManager = $this->getMockBuilder('Drupal\Core\Theme\ThemeManagerInterface')
+      ->disableOriginalConstructor()
+      ->getMock();
     $this->libraryDiscoveryParser = $this->getMockBuilder('Drupal\Core\Asset\LibraryDiscoveryParser')
       ->disableOriginalConstructor()
       ->getMock();
 
-    $this->libraryDiscoveryCollector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser);
   }
 
   /**
@@ -75,6 +86,17 @@ protected function setUp() {
    * @covers ::resolveCacheMiss
    */
   public function testResolveCacheMiss() {
+    $this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->themeManager->expects($this->once())
+      ->method('getActiveTheme')
+      ->will($this->returnValue($this->activeTheme));
+    $this->activeTheme->expects($this->once())
+      ->method('getName')
+      ->will($this->returnValue('kitten_theme'));
+    $this->libraryDiscoveryCollector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser, $this->themeManager);
+
     $this->libraryDiscoveryParser->expects($this->once())
       ->method('buildByExtension')
       ->with('test')
@@ -90,12 +112,23 @@ public function testResolveCacheMiss() {
    * @covers ::destruct
    */
   public function testDestruct() {
+    $this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->themeManager->expects($this->once())
+      ->method('getActiveTheme')
+      ->will($this->returnValue($this->activeTheme));
+    $this->activeTheme->expects($this->once())
+      ->method('getName')
+      ->will($this->returnValue('kitten_theme'));
+    $this->libraryDiscoveryCollector = new LibraryDiscoveryCollector($this->cache, $this->lock, $this->libraryDiscoveryParser, $this->themeManager);
+
     $this->libraryDiscoveryParser->expects($this->once())
       ->method('buildByExtension')
       ->with('test')
       ->will($this->returnValue($this->libraryData));
 
-    $lock_key = 'library_info:Drupal\Core\Cache\CacheCollector';
+    $lock_key = 'library_info:kitten_theme:Drupal\Core\Cache\CacheCollector';
 
     $this->lock->expects($this->once())
       ->method('acquire')
@@ -103,11 +136,11 @@ public function testDestruct() {
       ->will($this->returnValue(TRUE));
     $this->cache->expects($this->exactly(2))
       ->method('get')
-      ->with('library_info')
+      ->with('library_info:kitten_theme')
       ->will($this->returnValue(FALSE));
     $this->cache->expects($this->once())
       ->method('set')
-      ->with('library_info', array('test' => $this->libraryData), Cache::PERMANENT, array('library_info'));
+      ->with('library_info:kitten_theme', array('test' => $this->libraryData), Cache::PERMANENT, ['library_info']);
     $this->lock->expects($this->once())
       ->method('release')
       ->with($lock_key);
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index 528e579..2980040 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -52,6 +52,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
   protected $moduleHandler;
 
   /**
+   * The mocked theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $themeManager;
+
+  /**
    * The mocked lock backend.
    *
    * @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -65,7 +72,8 @@ protected function setUp() {
     parent::setUp();
 
     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler);
+    $this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager);
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryTest.php
index 343f51a..3492439 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryTest.php
@@ -38,6 +38,20 @@ class LibraryDiscoveryTest extends UnitTestCase {
   protected $moduleHandler;
 
   /**
+   * The mocked theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $themeManager;
+
+  /**
+   * The cache tags invalidator.
+   *
+   * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $cacheTagsInvalidator;
+
+  /**
    * Test library data.
    *
    * @var array
@@ -63,11 +77,13 @@ class LibraryDiscoveryTest extends UnitTestCase {
   protected function setUp() {
     parent::setUp();
 
+    $this->cacheTagsInvalidator = $this->getMock('Drupal\Core\Cache\CacheTagsInvalidatorInterface');
     $this->libraryDiscoveryCollector = $this->getMockBuilder('Drupal\Core\Asset\LibraryDiscoveryCollector')
       ->disableOriginalConstructor()
       ->getMock();
     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
-    $this->libraryDiscovery = new LibraryDiscovery($this->libraryDiscoveryCollector, $this->moduleHandler);
+    $this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
+    $this->libraryDiscovery = new LibraryDiscovery($this->libraryDiscoveryCollector, $this->cacheTagsInvalidator, $this->moduleHandler, $this->themeManager);
   }
 
   /**
@@ -85,6 +101,13 @@ public function testGetLibrariesByExtension() {
         $this->logicalOr($this->libraryData['test_1'], $this->libraryData['test_2']),
         $this->logicalOr('test/test_1', 'test/test_2')
       );
+    $this->themeManager->expects($this->exactly(2))
+      ->method('alter')
+      ->with(
+        'library',
+        $this->logicalOr($this->libraryData['test_1'], $this->libraryData['test_2']),
+        $this->logicalOr('test/test_1', 'test/test_2')
+      );
 
     $this->libraryDiscovery->getLibrariesbyExtension('test');
     // Verify that subsequent calls don't trigger hook_library_info_alter()
