diff --git a/core/core.services.yml b/core/core.services.yml
index 5877a38..2b92f75 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1501,7 +1501,7 @@ services:
       - { name: needs_destruction }
   library.discovery.parser:
     class: Drupal\Core\Asset\LibraryDiscoveryParser
-    arguments: ['@app.root', '@module_handler', '@theme.manager']
+    arguments: ['@app.root', '@module_handler', '@theme.manager', '@theme_handler', '@info_parser']
   library.dependency_resolver:
     class: Drupal\Core\Asset\LibraryDependencyResolver
     arguments: ['@library.discovery']
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 9acda6a..99421f4 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -6,7 +6,9 @@
 use Drupal\Core\Asset\Exception\InvalidLibrariesOverrideSpecificationException;
 use Drupal\Core\Asset\Exception\InvalidLibraryFileException;
 use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException;
+use Drupal\Core\Extension\InfoParserInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\Theme\ThemeManagerInterface;
 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
 use Drupal\Component\Serialization\Yaml;
@@ -31,6 +33,20 @@ class LibraryDiscoveryParser {
    */
   protected $themeManager;
 
+  /**
+   * The theme handler.
+   *
+   * @var \Drupal\Core\Extension\ThemeHandlerInterface
+   */
+  protected $themeHandler;
+
+  /**
+   * The info parser.
+   *
+   * @var \Drupal\Core\Extension\InfoParserInterface
+   */
+  protected $infoParser;
+
   /**
    * The app root.
    *
@@ -47,11 +63,17 @@ class LibraryDiscoveryParser {
    *   The module handler.
    * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
    *   The theme manager.
+   * @param \Drupal\Core\Theme\ThemeHandlerInterface $theme_handler
+   *   The theme handler.
+   * @param \Drupal\Core\Extension\InfoParserInterface $info_parser
+   *   The info parser.
    */
-  public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) {
+  public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, ThemeHandlerInterface $theme_handler, InfoParserInterface $info_parser) {
     $this->root = $root;
     $this->moduleHandler = $module_handler;
     $this->themeManager = $theme_manager;
+    $this->themeHandler = $theme_handler;
+    $this->infoParser = $info_parser;
   }
 
   /**
@@ -99,9 +121,25 @@ public function buildByExtension($extension) {
       }
 
       if (isset($library['version'])) {
-        // @todo Retrieve version of a non-core extension.
         if ($library['version'] === 'VERSION') {
-          $library['version'] = \Drupal::VERSION;
+          if ($extension_type === 'core' || strpos($path, 'core/modules/') === 0 || strpos($path, 'core/themes/') === 0) {
+            $library['version'] = \Drupal::VERSION;
+          }
+          else {
+            if ($extension_type === 'module') {
+              $info = $this->infoParser->parse($this->moduleHandler->getModule($extension)->getPathname());
+              $library['version'] = !empty($info['version']) ? $info['version'] : \Drupal::VERSION;
+            }
+            elseif ($extension_type === 'theme') {
+              $info = $this->infoParser->parse($this->themeHandler->getTheme($extension)->getPathname());
+              $library['version'] = !empty($info['version']) ? $info['version'] : \Drupal::VERSION;
+            }
+
+            // Extension *.info.yml file included 'version: VERSION'.
+            if ($library['version'] === 'VERSION') {
+              $library['version'] = \Drupal:VERSION;
+            }
+          }
         }
         // Remove 'v' prefix from external library versions.
         elseif ($library['version'][0] === 'v') {
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index ed0c9ce..6e6e0ac 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -44,6 +44,19 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
    */
   protected $themeManager;
 
+  /**
+   * The mocked theme handler.
+   *
+   * @var \Drupal\Core\Extension\ThemeHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+
+  /**
+   * The mocked info parser.
+   *
+   * @var \Drupal\Core\Extension\InfoParserInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $infoParser;
+
   /**
    * The mocked lock backend.
    *
@@ -59,6 +72,8 @@ protected function setUp() {
 
     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
     $this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
+    $this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
+    $this->infoParser = $this->getMock('\Drupal\Core\Extension\InfoParser');
     $mock_active_theme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
       ->disableOriginalConstructor()
       ->getMock();
@@ -68,7 +83,7 @@ protected function setUp() {
     $this->themeManager->expects($this->any())
       ->method('getActiveTheme')
       ->willReturn($mock_active_theme);
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->themeHandler $this->infoParser);
   }
 
   /**
@@ -82,6 +97,18 @@ public function testBuildByExtensionSimple() {
       ->with('example_module')
       ->will($this->returnValue(TRUE));
 
+    $mockExtension = $this->getMockBuilder('Drupal\Core\Extension\Extension')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('getModule')
+      ->with('example_module')
+      ->will($this->returnValue($mockExtension));
+
+    $this->infoParser->expects($this->atLeastOnce())
+      ->method('parse')
+      ->will($this->returnValue(['version' => 'VERSION']));
+
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'example_module', $path);
@@ -182,21 +209,33 @@ public function testBuildByExtensionWithMissingInformation() {
   }
 
   /**
-   * Tests the version property, and how it propagates to the contained assets.
+   * Tests the version property, and how it propagates to the module assets.
    *
    * @covers ::buildByExtension
    */
-  public function testVersion() {
+  public function testModuleVersion() {
+
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('moduleExists')
-      ->with('versions')
+      ->with('versions_module')
       ->will($this->returnValue(TRUE));
+    $mockExtension = $this->getMockBuilder('Drupal\Core\Extension\Extension')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('getModule')
+      ->with('versions_module')
+      ->will($this->returnValue($mockExtension));
+    $this->infoParser->expects($this->atLeastOnce())
+      ->method('parse')
+      ->with($this->stringEndsWith('versions_module.info.yml'))
+      ->will($this->returnValue(['version' => '8.x-1.2']));
 
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'versions', $path);
+    $this->libraryDiscoveryParser->setPaths('module', 'versions_module', $path);
 
-    $libraries = $this->libraryDiscoveryParser->buildByExtension('versions');
+    $libraries = $this->libraryDiscoveryParser->buildByExtension('versions_module');
 
     $this->assertFalse(array_key_exists('version', $libraries['versionless']));
     $this->assertEquals(-1, $libraries['versionless']['css'][0]['version']);
@@ -206,9 +245,51 @@ public function testVersion() {
     $this->assertEquals('9.8.7.6', $libraries['versioned']['css'][0]['version']);
     $this->assertEquals('9.8.7.6', $libraries['versioned']['js'][0]['version']);
 
-    $this->assertEquals(\Drupal::VERSION, $libraries['core-versioned']['version']);
-    $this->assertEquals(\Drupal::VERSION, $libraries['core-versioned']['css'][0]['version']);
-    $this->assertEquals(\Drupal::VERSION, $libraries['core-versioned']['js'][0]['version']);
+    $this->assertEquals('8.x-1.2', $libraries['module-versioned']['version']);
+    $this->assertEquals('8.x-1.2', $libraries['module-versioned']['css'][0]['version']);
+    $this->assertEquals('8.x-1.2', $libraries['module-versioned']['js'][0]['version']);
+  }
+
+  /**
+   * Tests the version property, and how it propagates to the theme assets.
+   *
+   * @covers ::buildByExtension
+   */
+  public function testThemeVersion() {
+
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('versions_theme')
+      ->will($this->returnValue(FALSE));
+    $mockExtension = $this->getMockBuilder('Drupal\Core\Extension\Extension')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->themeHandler->expects($this->atLeastOnce())
+      ->method('getTheme')
+      ->with('versions_theme')
+      ->will($this->returnValue($mockExtension));
+    $this->infoParser->expects($this->atLeastOnce())
+      ->method('parse')
+      ->with($this->stringEndsWith('versions_theme.info.yml'))
+      ->will($this->returnValue(['version' => '8.x-1.2']));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen($this->root) + 1);
+    $this->libraryDiscoveryParser->setPaths('theme', 'versions_theme', $path);
+
+    $libraries = $this->libraryDiscoveryParser->buildByExtension('versions_theme');
+
+    $this->assertFalse(array_key_exists('version', $libraries['versionless']));
+    $this->assertEquals(-1, $libraries['versionless']['css'][0]['version']);
+    $this->assertEquals(-1, $libraries['versionless']['js'][0]['version']);
+
+    $this->assertEquals('9.8.7.6', $libraries['versioned']['version']);
+    $this->assertEquals('9.8.7.6', $libraries['versioned']['css'][0]['version']);
+    $this->assertEquals('9.8.7.6', $libraries['versioned']['js'][0]['version']);
+
+    $this->assertEquals('8.x-1.2', $libraries['theme-versioned']['version']);
+    $this->assertEquals('8.x-1.2', $libraries['theme-versioned']['css'][0]['version']);
+    $this->assertEquals('8.x-1.2', $libraries['theme-versioned']['js'][0]['version']);
   }
 
   /**
@@ -224,14 +305,24 @@ public function testVersion() {
   public function testNonStringVersion() {
     $this->moduleHandler->expects($this->atLeastOnce())
       ->method('moduleExists')
-      ->with('versions')
+      ->with('versions_module')
       ->will($this->returnValue(TRUE));
 
+    // Need to mock this because the 'module-versioned' library is still
+    // processed.
+    $mockExtension = $this->getMockBuilder('Drupal\Core\Extension\Extension')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->moduleHandler
+      ->method('getModule')
+      ->with('versions_module')
+      ->will($this->returnValue($mockExtension));
+
     $path = __DIR__ . '/library_test_files';
     $path = substr($path, strlen($this->root) + 1);
-    $this->libraryDiscoveryParser->setPaths('module', 'versions', $path);
+    $this->libraryDiscoveryParser->setPaths('module', 'versions_module', $path);
 
-    $libraries = $this->libraryDiscoveryParser->buildByExtension('versions');
+    $libraries = $this->libraryDiscoveryParser->buildByExtension('versions_module');
 
     // As an example, we defined an ISO date in the YAML file and the YAML
     // parser converts it into a UNIX timestamp.
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions_module.libraries.yml
similarity index 82%
rename from core/tests/Drupal/Tests/Core/Asset/library_test_files/versions.libraries.yml
rename to core/tests/Drupal/Tests/Core/Asset/library_test_files/versions_module.libraries.yml
index bee49f5..1b5d77a 100644
--- a/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions.libraries.yml
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions_module.libraries.yml
@@ -13,13 +13,13 @@ versioned:
   js:
     versioned.js: {}
 
-core-versioned:
+module-versioned:
   version: VERSION
   css:
     theme:
-      core-versioned.css: {}
+      module-versioned.css: {}
   js:
-    core-versioned.js: {}
+    module-versioned.js: {}
 
 invalid-version:
   version: 2014-12-13
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions_theme.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions_theme.libraries.yml
new file mode 100644
index 0000000..4fa7f64
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/versions_theme.libraries.yml
@@ -0,0 +1,22 @@
+versionless:
+  css:
+    theme:
+      versionless.css: {}
+  js:
+    versionless.js: {}
+
+versioned:
+  version: "9.8.7.6"
+  css:
+    theme:
+      versioned.css: {}
+  js:
+    versioned.js: {}
+
+theme-versioned:
+  version: VERSION
+  css:
+    theme:
+      module-versioned.css: {}
+  js:
+    module-versioned.js: {}
