diff --git a/core/lib/Drupal/Core/Path/AliasStorage.php b/core/lib/Drupal/Core/Path/AliasStorage.php
index 899c39e..657f928 100644
--- a/core/lib/Drupal/Core/Path/AliasStorage.php
+++ b/core/lib/Drupal/Core/Path/AliasStorage.php
@@ -14,6 +14,9 @@
 
 /**
  * Provides a class for CRUD operations on path aliases.
+ *
+ * All queries use case-insensitive implementations, so '/test-alias' and
+ * '/test-Alias' is treated as equal.
  */
 class AliasStorage implements AliasStorageInterface {
   /**
@@ -98,7 +101,8 @@ public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NO
   public function load($conditions) {
     $select = $this->connection->select('url_alias');
     foreach ($conditions as $field => $value) {
-      $select->condition($field, $value);
+      // Use LIKE for case-insensitive matching.
+      $select->condition($field, $this->connection->escapeLike($value), 'LIKE');
     }
     return $select
       ->fields('url_alias')
@@ -115,7 +119,8 @@ public function delete($conditions) {
     $path = $this->load($conditions);
     $query = $this->connection->delete('url_alias');
     foreach ($conditions as $field => $value) {
-      $query->condition($field, $value);
+      // Use LIKE for case-insensitive matching.
+      $query->condition($field, $this->connection->escapeLike($value), 'LIKE');
     }
     $deleted = $query->execute();
     // @todo Switch to using an event for this instead of a hook.
@@ -160,20 +165,20 @@ public function preloadPathAlias($preloaded, $langcode) {
    */
   public function lookupPathAlias($path, $langcode) {
     $args = array(
-      ':source' => $path,
+      ':source' => $this->connection->escapeLike($path),
       ':langcode' => $langcode,
       ':langcode_undetermined' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
     );
-    // See the queries above.
+    // See the queries above. Use LIKE for case-insensitive matching.
     if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
       unset($args[':langcode']);
-      $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode = :langcode_undetermined ORDER BY pid DESC", $args)->fetchField();
+      $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source LIKE :source AND langcode = :langcode_undetermined ORDER BY pid DESC", $args)->fetchField();
     }
     elseif ($langcode > LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-      $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args)->fetchField();
+      $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source LIKE :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args)->fetchField();
     }
     else {
-      $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args)->fetchField();
+      $alias = $this->connection->query("SELECT alias FROM {url_alias} WHERE source LIKE :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args)->fetchField();
     }
 
     return $alias;
@@ -184,20 +189,20 @@ public function lookupPathAlias($path, $langcode) {
    */
   public function lookupPathSource($path, $langcode) {
     $args = array(
-      ':alias' => $path,
+      ':alias' => $this->connection->escapeLike($path),
       ':langcode' => $langcode,
       ':langcode_undetermined' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
     );
-    // See the queries above.
+    // See the queries above. Use LIKE for case-insensitive matching.
     if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
       unset($args[':langcode']);
-      $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode = :langcode_undetermined ORDER BY pid DESC", $args);
+      $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias LIKE :alias AND langcode = :langcode_undetermined ORDER BY pid DESC", $args);
     }
     elseif ($langcode > LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-      $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args);
+      $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias LIKE :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid DESC", $args);
     }
     else {
-      $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args);
+      $result = $this->connection->query("SELECT source FROM {url_alias} WHERE alias LIKE :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid DESC", $args);
     }
 
     return $result->fetchField();
@@ -207,11 +212,12 @@ public function lookupPathSource($path, $langcode) {
    * {@inheritdoc}
    */
   public function aliasExists($alias, $langcode, $source = NULL) {
+    // Use LIKE and NOT LIKE for case-insensitive matching.
     $query = $this->connection->select('url_alias')
-      ->condition('alias', $alias)
+      ->condition('alias', $this->connection->escapeLike($alias), 'LIKE')
       ->condition('langcode', $langcode);
     if (!empty($source)) {
-      $query->condition('source', $source, '<>');
+      $query->condition('source', $this->connection->escapeLike($source), 'NOT LIKE');
     }
     $query->addExpression('1');
     $query->range(0, 1);
diff --git a/core/lib/Drupal/Core/Path/AliasStorageInterface.php b/core/lib/Drupal/Core/Path/AliasStorageInterface.php
index 5ac77a3..a416fec 100644
--- a/core/lib/Drupal/Core/Path/AliasStorageInterface.php
+++ b/core/lib/Drupal/Core/Path/AliasStorageInterface.php
@@ -44,6 +44,8 @@ public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NO
   /**
    * Fetches a specific URL alias from the database.
    *
+   * The default implementation provides a case-insensitive implementation.
+   *
    * @param array $conditions
    *   An array of query conditions.
    *
@@ -60,6 +62,8 @@ public function load($conditions);
   /**
    * Deletes a URL alias.
    *
+   * The default implementation provides a case-insensitive implementation.
+   *
    * @param array $conditions
    *   An array of criteria.
    */
@@ -82,6 +86,8 @@ public function preloadPathAlias($preloaded, $langcode);
   /**
    * Returns an alias of Drupal system URL.
    *
+   * The default implementation provides a case-insensitive implementation.
+   *
    * @param string $path
    *   The path to investigate for corresponding path aliases.
    * @param string $langcode
@@ -96,6 +102,8 @@ public function lookupPathAlias($path, $langcode);
   /**
    * Returns Drupal system URL of an alias.
    *
+   * The default implementation provides a case-insensitive implementation.
+   *
    * @param string $path
    *   The path to investigate for corresponding system URLs.
    * @param string $langcode
@@ -110,6 +118,8 @@ public function lookupPathSource($path, $langcode);
   /**
    * Checks if alias already exists.
    *
+   * The default implementation provides a case-insensitive implementation.
+   *
    * @param string $alias
    *   Alias to check against.
    * @param string $langcode
@@ -135,8 +145,9 @@ public function languageAliasExists();
    *
    * @param array $header
    *   Table header.
-   * @param string[]|null $keys
-   *   (optional) Search keys.
+   * @param string|null $keys
+   *   (optional) Search keyword that may include one or more '*' as a wildcard
+   *   value.
    *
    * @return array
    *   Array of items to be displayed on the current page.
diff --git a/core/modules/path/src/Form/PathFormBase.php b/core/modules/path/src/Form/PathFormBase.php
index 8c84841..5d75346 100644
--- a/core/modules/path/src/Form/PathFormBase.php
+++ b/core/modules/path/src/Form/PathFormBase.php
@@ -180,8 +180,16 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $langcode = $form_state->getValue('langcode', LanguageInterface::LANGCODE_NOT_SPECIFIED);
 
     if ($this->aliasStorage->aliasExists($alias, $langcode, $this->path['source'])) {
-      $form_state->setErrorByName('alias', t('The alias %alias is already in use in this language.', array('%alias' => $alias)));
+      $stored_alias = $this->aliasStorage->load(['alias' => $alias, 'langcode' => $langcode]);
+      if ($stored_alias['alias'] !== $alias) {
+        $form_state->setErrorByName('alias', t('There is an alias with other case-sensitivity: %actual_alias is already in use in this language.', ['%actual_alias' => $stored_alias['alias']]));
+      }
+      else {
+        $form_state->setErrorByName('alias', t('The alias %alias is already in use in this language.', array('%alias' => $alias)));
+      }
     }
+
+
     if (!$this->pathValidator->isValid(trim($source, '/'))) {
       $form_state->setErrorByName('source', t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $source)));
     }
diff --git a/core/modules/path/src/Tests/PathAliasTest.php b/core/modules/path/src/Tests/PathAliasTest.php
index 651c11f..4f62bd6 100644
--- a/core/modules/path/src/Tests/PathAliasTest.php
+++ b/core/modules/path/src/Tests/PathAliasTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\path\Tests;
 
+use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Cache\Cache;
 
 /**
@@ -82,6 +83,13 @@ function testAdminAlias() {
     $this->drupalGet($edit['alias']);
     $this->assertText($node1->label(), 'Alias works.');
     $this->assertResponse(200);
+    // Confirm that the alias works in a case-insensitive way.
+    $this->drupalGet(Unicode::strtolower($edit['alias']));
+    $this->assertText($node1->label(), 'Alias works lower case.');
+    $this->assertResponse(200);
+    $this->drupalGet(Unicode::strtoupper($edit['alias']));
+    $this->assertText($node1->label(), 'Alias works upper case.');
+    $this->assertResponse(200);
 
     // Change alias to one containing "exotic" characters.
     $pid = $this->getPID($edit['alias']);
@@ -93,7 +101,7 @@ function testAdminAlias() {
     $this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
 
     // Confirm that the alias works.
-    $this->drupalGet($edit['alias']);
+    $this->drupalGet(Unicode::strtolower($edit['alias']));
     $this->assertText($node1->label(), 'Changed alias works.');
     $this->assertResponse(200);
 
@@ -225,7 +233,7 @@ function testNodeAlias() {
     $this->drupalPostForm('node/' . $node1->id() . '/edit', $edit, t('Save'));
 
     // Confirm that the alias works.
-    $this->drupalGet($edit['path[0][alias]']);
+    $this->drupalGet(Unicode::strtolower($edit['path[0][alias]']));
     $this->assertText($node1->label(), 'Changed alias works.');
     $this->assertResponse(200);
 
diff --git a/core/tests/Drupal/KernelTests/Core/Path/AliasStorageTest.php b/core/tests/Drupal/KernelTests/Core/Path/AliasStorageTest.php
new file mode 100644
index 0000000..98180e3
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Path/AliasStorageTest.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\KernelTests\Core\Path\AliasStorageTest.
+ */
+
+namespace Drupal\KernelTests\Core\Path;
+
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Path\AliasStorage
+ * @group path
+ */
+class AliasStorageTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['system'];
+
+  /** @var \Drupal\Core\Path\AliasStorage */
+  protected $storage;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installSchema('system', 'url_alias');
+    $this->storage = $this->container->get('path.alias_storage');
+  }
+
+  /**
+   * @covers ::load
+   */
+  public function testLoad() {
+    $this->storage->save('/test-source-Case', '/test-alias-Case');
+
+    $expected = [
+      'pid' => 1,
+      'alias' => '/test-alias-Case',
+      'source' => '/test-source-Case',
+      'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+    ];
+
+    $this->assertEquals($expected, $this->storage->load(['alias' => '/test-alias-Case']));
+    $this->assertEquals($expected, $this->storage->load(['alias' => '/test-alias-case']));
+    $this->assertEquals($expected, $this->storage->load(['source' => '/test-source-Case']));
+    $this->assertEquals($expected, $this->storage->load(['source' => '/test-source-case']));
+  }
+
+  /**
+   * @covers ::lookupPathAlias
+   */
+  public function testLookupPathAlias() {
+    $this->storage->save('/test-source-Case', '/test-alias');
+
+    $this->assertEquals('/test-alias', $this->storage->lookupPathAlias('/test-source-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
+    $this->assertEquals('/test-alias', $this->storage->lookupPathAlias('/test-source-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
+  }
+
+  /**
+   * @covers ::lookupPathSource
+   */
+  public function testLookupPathSource() {
+    $this->storage->save('/test-source', '/test-alias-Case');
+
+    $this->assertEquals('/test-source', $this->storage->lookupPathSource('/test-alias-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
+    $this->assertEquals('/test-source', $this->storage->lookupPathSource('/test-alias-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
+  }
+
+  /**
+   * @covers ::aliasExists
+   */
+  public function testAliasExists() {
+    $this->storage->save('/test-source-Case', '/test-alias-Case');
+
+    $this->assertTrue($this->storage->aliasExists('/test-alias-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
+    $this->assertTrue($this->storage->aliasExists('/test-alias-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
+  }
+
+}
