diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 799ee07..495fed0 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -39,6 +39,26 @@ class LibraryDiscoveryParser {
   protected $root;
 
   /**
+   * The list of asset paths / sources that have libraries-override applied.
+   *
+   * @var array
+   */
+  protected $overriddenLibraryPaths = [];
+
+  /**
+   * Used to retrieve original libraries-override keys from base theme paths.
+   *
+   * This is used to maintain backward compatibility with previous
+   * libraries-override behavior where overriding of already overridden paths
+   * required using the full Drupal-root-relative path of the last override.
+   *
+   * @todo Remove when BC-break is allowed.
+   *
+   * @var array
+   */
+  protected $originalLibraryPaths = [];
+
+  /**
    * Constructs a new LibraryDiscoveryParser instance.
    *
    * @param string $root
@@ -143,6 +163,11 @@ public function buildByExtension($extension) {
         }
         foreach ($library[$type] as $source => $options) {
           unset($library[$type][$source]);
+          // Update to the overridden source in libraries-override.
+          if (!($source = $this->getLatestOverridePath($source, $type, $id, $extension))) {
+            // Don't bother if the override says 'false'.
+            continue;
+          }
           // Allow to omit the options hashmap in YAML declarations.
           if (!is_array($options)) {
             $options = array();
@@ -335,8 +360,8 @@ protected function applyLibrariesOverride($libraries, $extension) {
     // ActiveTheme::getLibrariesOverride() returns libraries-overrides for the
     // current theme as well as all its base themes.
     $all_libraries_overrides = $active_theme->getLibrariesOverride();
-    foreach ($all_libraries_overrides as $theme_path => $libraries_overrides) {
-      foreach ($libraries as $library_name => $library) {
+    foreach ($libraries as $library_name => $library) {
+      foreach ($all_libraries_overrides as $theme_path => $libraries_overrides) {
         // Process libraries overrides.
         if (isset($libraries_overrides["$extension/$library_name"])) {
           // Active theme defines an override for this library.
@@ -356,23 +381,23 @@ protected function applyLibrariesOverride($libraries, $extension) {
           elseif (is_array($override_definition)) {
             // An array definition implies an override for an asset within this
             // library.
-            foreach ($override_definition as $sub_key => $value) {
+            foreach ($override_definition as $type => $value) {
               // Throw an exception if the asset is not properly specified.
               if (!is_array($value)) {
-                throw new InvalidLibrariesOverrideSpecificationException(sprintf('Library asset %s is not correctly specified. It should be in the form "extension/library_name/sub_key/path/to/asset.js".', "$extension/$library_name/$sub_key"));
+                throw new InvalidLibrariesOverrideSpecificationException(sprintf('Library asset %s is not correctly specified. It should be in the form "extension/library_name/sub_key/path/to/asset.js".', "$extension/$library_name/$type"));
               }
-              if ($sub_key === 'drupalSettings') {
+              if ($type === 'drupalSettings') {
                 // drupalSettings may not be overridden.
-                throw new InvalidLibrariesOverrideSpecificationException(sprintf('drupalSettings may not be overridden in libraries-override. Trying to override %s. Use hook_library_info_alter() instead.', "$extension/$library_name/$sub_key"));
+                throw new InvalidLibrariesOverrideSpecificationException(sprintf('drupalSettings may not be overridden in libraries-override. Trying to override %s. Use hook_library_info_alter() instead.', "$extension/$library_name/$type"));
               }
-              elseif ($sub_key === 'css') {
+              elseif ($type === 'css') {
                 // SMACSS category should be incorporated into the asset name.
                 foreach ($value as $category => $overrides) {
-                  $this->setOverrideValue($libraries[$library_name], [$sub_key, $category], $overrides, $theme_path);
+                  $this->setOverrideValue($overrides, $type, $library_name, $extension, $theme_path);
                 }
               }
               else {
-                $this->setOverrideValue($libraries[$library_name], [$sub_key], $value, $theme_path);
+                $this->setOverrideValue($value, $type, $library_name, $extension, $theme_path);
               }
             }
           }
@@ -405,37 +430,38 @@ protected function isValidUri($string) {
   }
 
   /**
-   * Overrides the specified library asset.
+   * Stores the specified library-overrides for later implementation.
    *
-   * @param array $library
-   *   The containing library definition.
-   * @param array $sub_key
-   *   An array containing the sub-keys specifying the library asset, e.g.
-   *   @code['js']@endcode or @code['css', 'component']@endcode
    * @param array $overrides
    *   Specifies the overrides, this is an array where the key is the asset to
    *   be overridden while the value is overriding asset.
+   * @param string $type
+   *   The type of library asset, e.g. 'js' or 'css'.
+   * @param string $library_name
+   *   The name of the library being overridden.
+   * @param string $extension
+   *   The extension name.
+   * @param string $theme_path
+   *   The path to the theme defining the libraries-override.
    */
-  protected function setOverrideValue(array &$library, array $sub_key, array $overrides, $theme_path) {
+  protected function setOverrideValue(array $overrides, $type, $library_name, $extension, $theme_path) {
     foreach ($overrides as $original => $replacement) {
-      // Get the attributes of the asset to be overridden. If the key does
-      // not exist, then throw an exception.
-      $key_exists = NULL;
-      $parents = array_merge($sub_key, [$original]);
-      // Save the attributes of the library asset to be overridden.
-      $attributes = NestedArray::getValue($library, $parents, $key_exists);
-      if ($key_exists) {
-        // Remove asset to be overridden.
-        NestedArray::unsetValue($library, $parents);
-        // No need to replace if FALSE is specified, since that is a removal.
-        if ($replacement) {
-          // Ensure the replacement path is relative to drupal root.
-          $replacement = $this->resolveThemeAssetPath($theme_path, $replacement);
-          $new_parents = array_merge($sub_key, [$replacement]);
-          // Replace with an override if specified.
-          NestedArray::setValue($library, $new_parents, $attributes);
-        }
+      // $original can either be the last overridden path (also possibly
+      // using the '@themename' token) or the original library definition path.
+
+      // For BC we check if $original still refers to base-theme overrides.
+      // @todo Remove when BC-break is allowed.
+      if (isset($this->originalLibraryPaths[$this->expandThemePathToken($original)])) {
+        // Here $original actually refers to an overridden path (maybe from a
+        // base theme), so get the actual original path by which the library
+        // asset was keyed.
+        $original = $this->originalLibraryPaths[$this->expandThemePathToken($original)];
+      }
+      if ($replacement) {
+        $this->originalLibraryPaths[$this->resolveThemeAssetPath($theme_path, $replacement)] = $original;
       }
+
+      $this->setLatestOverridePath($this->resolveThemeAssetPath($theme_path, $replacement), $original, $type, $library_name, $extension);
     }
   }
 
@@ -444,13 +470,16 @@ protected function setOverrideValue(array &$library, array $sub_key, array $over
    *
    * @param string $theme_path
    *   The theme or base theme.
-   * @param string $overriding_asset
+   * @param string|false $overriding_asset
    *   The overriding library asset.
    *
    * @return string
    *   A fully resolved theme asset path relative to the Drupal directory.
    */
   protected function resolveThemeAssetPath($theme_path, $overriding_asset) {
+    if ($overriding_asset == FALSE) {
+      return FALSE;
+    }
     if ($overriding_asset[0] !== '/' && !$this->isValidUri($overriding_asset)) {
       // The destination is not an absolute path and it's not a URI (e.g.
       // public://generated_js/example.js or http://example.com/js/my_js.js), so
@@ -460,4 +489,63 @@ protected function resolveThemeAssetPath($theme_path, $overriding_asset) {
     return $overriding_asset;
   }
 
+  /**
+   * Gets the libraries-override path that applies to the library asset.
+   *
+   * @param string $original_path
+   *   The original library asset source path.
+   * @param string $type
+   *   The type of library asset, e.g. 'js' or 'css'.
+   * @param string $library_name
+   *   The library name or ID string.
+   * @param string $extension
+   *   The extension name.
+   *
+   * @return string
+   *   The full path to the effective libraries-override asset or $original_path
+   *   if the asset is not overridden.
+   */
+  protected function getLatestOverridePath($original_path, $type, $library_name, $extension) {
+    $key = $extension . ':' . $library_name . ':' . $type . ':' . $original_path;
+    return isset($this->overriddenLibraryPaths[$key])
+      ? $this->overriddenLibraryPaths[$key]
+      : $original_path;
+  }
+
+  /**
+   * Sets the libraries-override path that applies to the library asset.
+   *
+   * @param string $new_path
+   *   The Drupal-root-relative path to the overriding library asset.
+   * @param string $original_path
+   *   The original library asset source path.
+   * @param string $type
+   *   The type of library asset, e.g. 'js' or 'css'.
+   * @param string $library_name
+   *   The library name or ID string.
+   * @param string $extension
+   *   The extension name.
+   */
+  protected function setLatestOverridePath($new_path, $original_path, $type, $library_name, $extension) {
+    $this->overriddenLibraryPaths[$extension . ':' . $library_name . ':' . $type . ':' . $original_path] = $new_path;
+  }
+
+  /**
+   * Expands a theme path token.
+   *
+   * @param string $path
+   *   An asset path containing a theme token like '@stable'.
+   *
+   * @return string
+   *   The path with the token expanded to the full Drupal-root-relative path.
+   */
+  protected function expandThemePathToken($path) {
+    if (strpos($path, '@') === 0) {
+      list($theme_name, $sub_path) = explode('/', $path, 2);
+      $theme_name = substr($theme_name, 1);
+      $path = '/' . $this->drupalGetPath('theme', $theme_name) . '/' . $sub_path;
+    }
+    return $path;
+  }
+
 }
diff --git a/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml b/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml
index 7bf373a..b803dd3 100644
--- a/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml
+++ b/core/modules/system/tests/themes/test_subsubtheme/test_subsubtheme.info.yml
@@ -4,3 +4,12 @@ description: 'Test theme which uses test_subtheme as the base theme.'
 version: VERSION
 core: 8.x
 base theme: test_subtheme
+
+libraries-override:
+  core/drupal.dialog:
+    js:
+      misc/dialog/dialog.js: js/subsubtheme-dialog.js
+  core/jquery.farbtastic:
+    css:
+      component:
+        '@test_basetheme/css/farbtastic.css': css/subsubtheme-farbtastic.css
diff --git a/core/tests/Drupal/KernelTests/Core/Asset/LibraryDiscoveryIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/Asset/LibraryDiscoveryIntegrationTest.php
index a77adfc..addf6d8 100644
--- a/core/tests/Drupal/KernelTests/Core/Asset/LibraryDiscoveryIntegrationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Asset/LibraryDiscoveryIntegrationTest.php
@@ -161,6 +161,19 @@ public function testBaseThemeLibrariesOverrideInSubTheme() {
   }
 
   /**
+   * Tests library-override on already overridden libraries.
+   */
+  public function testLibrariesOverrideOverridden() {
+    // Activate a sub-theme that overrides a library override.
+    $this->activateTheme('test_subsubtheme');
+
+    // Assert that effective libraries override is from the test_subsubtheme.
+    $this->assertNoAssetInLibrary('core/modules/system/tests/themes/test_basetheme/css/farbtastic.css', 'core', 'jquery.farbtastic', 'css');
+    $this->assertAssetInLibrary('core/modules/system/tests/themes/test_subsubtheme/css/subsubtheme-farbtastic.css', 'core', 'jquery.farbtastic', 'css');
+    $this->assertAssetInLibrary('core/modules/system/tests/themes/test_subsubtheme/js/subsubtheme-dialog.js', 'core', 'drupal.dialog', 'js');
+  }
+
+  /**
    * Tests libraries-extend.
    */
   public function testLibrariesExtend() {
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index 121aebc..fa1b936 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -505,6 +505,27 @@ public function testLibraryWithLicenses() {
     $this->assertEquals($library['license'], $expected_license);
   }
 
+  /**
+   * @covers ::expandThemePathToken
+   */
+  public function testExpandThemePathToken() {
+    $this->libraryDiscoveryParser->setPaths('theme', 'theme_name', 'path/to/test/theme/name');
+    $expanded = $this->libraryDiscoveryParser->expandThemePathToken('@theme_name/css/component/something.css');
+    $this->assertEquals('/path/to/test/theme/name/css/component/something.css', $expanded);
+  }
+
+  /**
+   * @covers ::getLatestOverridePath
+   * @covers ::setLatestOverridePath
+   */
+  public function testLatestOverridePath() {
+    $latest = $this->libraryDiscoveryParser->getLatestOverridePath('original-path', 'type', 'extension', 'library_name');
+    $this->assertEquals('original-path', $latest);
+    $this->libraryDiscoveryParser->setLatestOverridePath('latest-path', 'original-path', 'type', 'extension', 'library_name');
+    $latest = $this->libraryDiscoveryParser->getLatestOverridePath('original-path', 'type', 'extension', 'library_name');
+    $this->assertEquals('latest-path', $latest);
+  }
+
 }
 
 /**
@@ -532,6 +553,18 @@ public function setFileValidUri($source, $valid) {
     $this->validUris[$source] = $valid;
   }
 
+  public function getLatestOverridePath($original_path, $type, $extension, $library_name) {
+    return parent::getLatestOverridePath($original_path, $type, $extension, $library_name);
+  }
+
+  public function setLatestOverridePath($new_path, $original_path, $type, $extension, $library_name) {
+    parent::setLatestOverridePath($new_path, $original_path, $type, $extension, $library_name);
+  }
+
+  public function expandThemePathToken($path) {
+    return parent::expandThemePathToken($path);
+  }
+
 }
 
 if (!defined('CSS_AGGREGATE_DEFAULT')) {
