diff --git a/core/core.services.yml b/core/core.services.yml
index 91a2c2b..d822949 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -252,10 +252,10 @@ services:
     class: Drupal\Core\Path\AliasWhitelist
     tags:
       - { name: needs_destruction }
-    arguments: [path_alias_whitelist, '@cache.default', '@lock', '@state', '@path.alias_storage']
+    arguments: [path_alias_whitelist, '@cache.default', '@lock', '@state', '@entity.manager']
   path.alias_manager:
     class: Drupal\Core\Path\AliasManager
-    arguments: ['@path.alias_storage', '@path.alias_whitelist', '@language_manager', '@cache.data']
+    arguments: ['@entity.manager', '@path.alias_whitelist', '@language_manager', '@cache.data']
   http_client:
     class: Drupal\Core\Http\Client
     tags:
@@ -544,11 +544,6 @@ services:
     arguments: ['@lock', '@plugin.manager.menu.link']
     tags:
       - { name: event_subscriber }
-  path.alias_storage:
-    class: Drupal\Core\Path\AliasStorage
-    arguments: ['@database', '@module_handler']
-    tags:
-      - { name: backend_overridable }
   path.matcher:
     class: Drupal\Core\Path\PathMatcher
     arguments: ['@config.factory']
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index f0b06dd..e268e34 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -827,7 +827,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
         // the necessary database tables.
         $entity_manager = \Drupal::entityManager();
         foreach ($entity_manager->getDefinitions() as $entity_type) {
-          if ($entity_type->getProvider() == $module) {
+          if (in_array($entity_type->getProvider(), array($module, 'core'))) {
             $entity_manager->onEntityTypeCreate($entity_type);
           }
         }
diff --git a/core/lib/Drupal/Core/Path/AliasInterface.php b/core/lib/Drupal/Core/Path/AliasInterface.php
new file mode 100644
index 0000000..16efa7a
--- /dev/null
+++ b/core/lib/Drupal/Core/Path/AliasInterface.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Path\AliasInterface.
+ */
+
+namespace Drupal\Core\Path;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+
+/**
+ * Provides an interface defining an alias entity.
+ */
+interface AliasInterface extends ContentEntityInterface {
+
+}
diff --git a/core/lib/Drupal/Core/Path/AliasManager.php b/core/lib/Drupal/Core/Path/AliasManager.php
index bca2eea..31a87cf 100644
--- a/core/lib/Drupal/Core/Path/AliasManager.php
+++ b/core/lib/Drupal/Core/Path/AliasManager.php
@@ -9,17 +9,18 @@
 
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\CacheDecorator\CacheDecoratorInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
 
 class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
 
   /**
-   * The alias storage service.
+   * The entity manager service.
    *
-   * @var \Drupal\Core\Path\AliasStorageInterface
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $storage;
+  protected $entityManager;
 
   /**
    * Cache backend service.
@@ -97,8 +98,8 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
   /**
    * Constructs an AliasManager.
    *
-   * @param \Drupal\Core\Path\AliasStorageInterface $storage
-   *   The alias storage service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    * @param \Drupal\Core\Path\AliasWhitelistInterface $whitelist
    *   The whitelist implementation to use.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
@@ -106,8 +107,8 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   Cache backend.
    */
-  public function __construct(AliasStorageInterface $storage, AliasWhitelistInterface $whitelist, LanguageManagerInterface $language_manager, CacheBackendInterface $cache) {
-    $this->storage = $storage;
+  public function __construct(EntityManagerInterface $entity_manager, AliasWhitelistInterface $whitelist, LanguageManagerInterface $language_manager, CacheBackendInterface $cache) {
+    $this->entityManager = $entity_manager;
     $this->languageManager = $language_manager;
     $this->whitelist = $whitelist;
     $this->cache = $cache;
@@ -170,7 +171,7 @@ public function getPathByAlias($alias, $langcode = NULL) {
     }
 
     // Look for path in storage.
-    if ($path = $this->storage->lookupPathSource($alias, $langcode)) {
+    if ($path = $this->entityManager->getStorage('alias')->lookupPathSource($alias, $langcode)) {
       $this->lookupMap[$langcode][$path] = $alias;
       $this->cacheNeedsWriting = TRUE;
       return $path;
@@ -217,7 +218,7 @@ public function getAliasByPath($path, $langcode = NULL) {
 
       // Load paths from cache.
       if (!empty($this->preloadedPathLookups[$langcode])) {
-        $this->lookupMap[$langcode] = $this->storage->preloadPathAlias($this->preloadedPathLookups[$langcode], $langcode);
+        $this->lookupMap[$langcode] = $this->entityManager->getStorage('alias')->preloadPathAlias($this->preloadedPathLookups[$langcode], $langcode);
         // Keep a record of paths with no alias to avoid querying twice.
         $this->noAlias[$langcode] = array_flip(array_diff_key($this->preloadedPathLookups[$langcode], array_keys($this->lookupMap[$langcode])));
       }
@@ -234,7 +235,7 @@ public function getAliasByPath($path, $langcode = NULL) {
     }
 
     // Try to load alias from storage.
-    if ($alias = $this->storage->lookupPathAlias($path, $langcode)) {
+    if ($alias = $this->entityManager->getStorage('alias')->lookupPathAlias($path, $langcode)) {
       $this->lookupMap[$langcode][$path] = $alias;
       $this->cacheNeedsWriting = TRUE;
       return $alias;
diff --git a/core/lib/Drupal/Core/Path/AliasStorage.php b/core/lib/Drupal/Core/Path/AliasStorage.php
index 153866b..d5b3b3f 100644
--- a/core/lib/Drupal/Core/Path/AliasStorage.php
+++ b/core/lib/Drupal/Core/Path/AliasStorage.php
@@ -7,109 +7,13 @@
 
 namespace Drupal\Core\Path;
 
-use Drupal\Core\Database\Connection;
-use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
 use Drupal\Core\Language\LanguageInterface;
 
 /**
- * Provides a class for CRUD operations on path aliases.
+ * Alias storage class.
  */
-class AliasStorage implements AliasStorageInterface {
-  /**
-   * The database connection.
-   *
-   * @var \Drupal\Core\Database\Connection
-   */
-  protected $connection;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Constructs a Path CRUD object.
-   *
-   * @param \Drupal\Core\Database\Connection $connection
-   *   A database connection for reading and writing path aliases.
-   *
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   */
-  public function __construct(Connection $connection, ModuleHandlerInterface $module_handler) {
-    $this->connection = $connection;
-    $this->moduleHandler = $module_handler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid = NULL) {
-
-    $fields = array(
-      'source' => $source,
-      'alias' => $alias,
-      'langcode' => $langcode,
-    );
-
-    // Insert or update the alias.
-    if (empty($pid)) {
-      $query = $this->connection->insert('url_alias')
-        ->fields($fields);
-      $pid = $query->execute();
-      $fields['pid'] = $pid;
-      $operation = 'insert';
-    }
-    else {
-      // Fetch the current values so that an update hook can identify what
-      // exactly changed.
-      $original = $this->connection->query('SELECT source, alias, langcode FROM {url_alias} WHERE pid = :pid', array(':pid' => $pid))->fetchAssoc();
-      $fields['pid'] = $pid;
-      $query = $this->connection->update('url_alias')
-        ->fields($fields)
-        ->condition('pid', $pid);
-      $pid = $query->execute();
-      $fields['original'] = $original;
-      $operation = 'update';
-    }
-    if ($pid) {
-      // @todo Switch to using an event for this instead of a hook.
-      $this->moduleHandler->invokeAll('path_' . $operation, array($fields));
-      return $fields;
-    }
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function load($conditions) {
-    $select = $this->connection->select('url_alias');
-    foreach ($conditions as $field => $value) {
-      $select->condition($field, $value);
-    }
-    return $select
-      ->fields('url_alias')
-      ->execute()
-      ->fetchAssoc();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function delete($conditions) {
-    $path = $this->load($conditions);
-    $query = $this->connection->delete('url_alias');
-    foreach ($conditions as $field => $value) {
-      $query->condition($field, $value);
-    }
-    $deleted = $query->execute();
-    // @todo Switch to using an event for this instead of a hook.
-    $this->moduleHandler->invokeAll('path_delete', array($path));
-    return $deleted;
-  }
+class AliasStorage extends SqlContentEntityStorage implements AliasStorageInterface {
 
   /**
    * {@inheritdoc}
@@ -130,13 +34,13 @@ public function preloadPathAlias($preloaded, $langcode) {
     if ($langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
       // Prevent PDO from complaining about a token the query doesn't use.
       unset($args[':langcode']);
-      $result = $this->connection->query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode = :langcode_undetermined ORDER BY pid ASC', $args);
+      $result = $this->database->query('SELECT path, alias FROM {alias_field_data} WHERE path IN (:system) AND langcode = :langcode_undetermined ORDER BY aid ASC', $args);
     }
     elseif ($langcode < LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-      $result = $this->connection->query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, pid ASC', $args);
+      $result = $this->database->query('SELECT path, alias FROM {alias_field_data} WHERE path IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, aid ASC', $args);
     }
     else {
-      $result = $this->connection->query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, pid ASC', $args);
+      $result = $this->database->query('SELECT path, alias FROM {alias_field_data} WHERE path IN (:system) AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, aid ASC', $args);
     }
 
     return $result->fetchAllKeyed();
@@ -154,13 +58,13 @@ public function lookupPathAlias($path, $langcode) {
     // See the queries above.
     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->database->query("SELECT alias FROM {alias_field_data} WHERE path = :source AND langcode = :langcode_undetermined ORDER BY aid 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->database->query("SELECT alias FROM {alias_field_data} WHERE path = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, aid 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->database->query("SELECT alias FROM {alias_field_data} WHERE path = :source AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, aid DESC", $args)->fetchField();
     }
 
     return $alias;
@@ -178,13 +82,13 @@ public function lookupPathSource($path, $langcode) {
     // See the queries above.
     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->database->query("SELECT path FROM {alias_field_data} WHERE alias = :alias AND langcode = :langcode_undetermined ORDER BY aid 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->database->query("SELECT path FROM {alias_field_data} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode DESC, aid 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->database->query("SELECT path FROM {alias_field_data} WHERE alias = :alias AND langcode IN (:langcode, :langcode_undetermined) ORDER BY langcode ASC, aid DESC", $args);
     }
 
     return $result->fetchField();
@@ -203,11 +107,11 @@ public function lookupPathSource($path, $langcode) {
    *   TRUE if alias already exists and FALSE otherwise.
    */
   public function aliasExists($alias, $langcode, $source = NULL) {
-    $query = $this->connection->select('url_alias')
+    $query = $this->database->select('alias_field_data')
       ->condition('alias', $alias)
       ->condition('langcode', $langcode);
     if (!empty($source)) {
-      $query->condition('source', $source, '<>');
+      $query->condition('path', $source, '<>');
     }
     $query->addExpression('1');
     $query->range(0, 1);
@@ -221,7 +125,7 @@ public function aliasExists($alias, $langcode, $source = NULL) {
    *   TRUE if aliases with language exist.
    */
   public function languageAliasExists() {
-    return (bool) $this->connection->queryRange('SELECT 1 FROM {url_alias} WHERE langcode <> :langcode', 0, 1, array(':langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED))->fetchField();
+    return (bool) $this->database->queryRange('SELECT 1 FROM {alias_field_data} WHERE langcode <> :langcode', 0, 1, array(':langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED))->fetchField();
   }
 
   /**
@@ -235,7 +139,7 @@ public function languageAliasExists() {
    *   Array of items to be displayed on the current page.
    */
   public function getAliasesForAdminListing($header, $keys = NULL) {
-    $query = $this->connection->select('url_alias')
+    $query = $this->database->select('alias_field_data')
       ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
       ->extend('Drupal\Core\Database\Query\TableSortExtender');
     if ($keys) {
@@ -243,7 +147,7 @@ public function getAliasesForAdminListing($header, $keys = NULL) {
       $query->condition('alias', '%' . preg_replace('!\*+!', '%', $keys) . '%', 'LIKE');
     }
     return $query
-      ->fields('url_alias')
+      ->fields('alias_field_data')
       ->orderByHeader($header)
       ->limit(50)
       ->execute()
@@ -260,10 +164,10 @@ public function getAliasesForAdminListing($header, $keys = NULL) {
    *   TRUE if any alias exists, FALSE otherwise.
    */
   public function pathHasMatchingAlias($initial_substring) {
-    $query = $this->connection->select('url_alias', 'u');
+    $query = $this->database->select('alias_field_data', 'u');
     $query->addExpression(1);
     return (bool) $query
-      ->condition('u.source', $this->connection->escapeLike($initial_substring) . '%', 'LIKE')
+      ->condition('u.path', $this->database->escapeLike($initial_substring) . '%', 'LIKE')
       ->range(0, 1)
       ->execute()
       ->fetchField();
diff --git a/core/lib/Drupal/Core/Path/AliasStorageInterface.php b/core/lib/Drupal/Core/Path/AliasStorageInterface.php
index 30364fd..65ce950 100644
--- a/core/lib/Drupal/Core/Path/AliasStorageInterface.php
+++ b/core/lib/Drupal/Core/Path/AliasStorageInterface.php
@@ -7,60 +7,13 @@
 
 namespace Drupal\Core\Path;
 
-use Drupal\Core\Language\LanguageInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
+
 
 /**
- * Provides a class for CRUD operations on path aliases.
+ * Alias storage interface.
  */
-interface AliasStorageInterface {
-
-  /**
-   * Saves a path alias to the database.
-   *
-   * @param string $source
-   *   The internal system path.
-   * @param string $alias
-   *   The URL alias.
-   * @param string $langcode
-   *   The language code of the alias.
-   * @param int|null $pid
-   *   Unique path alias identifier.
-   *
-   * @return mixed[]|bool
-   *   FALSE if the path could not be saved or an associative array containing
-   *   the following keys:
-   *   - source (string): The internal system path.
-   *   - alias (string): The URL alias.
-   *   - pid (int): Unique path alias identifier.
-   *   - langcode (string): The language code of the alias.
-   *   - original: For updates, an array with source, alias and langcode with
-   *     the previous values.
-   */
-  public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid = NULL);
-
-  /**
-   * Fetches a specific URL alias from the database.
-   *
-   * @param $conditions
-   *   An array of query conditions.
-   *
-   * @return mixed[]|bool
-   *   FALSE if no alias was found or an associative array containing the
-   *   following keys:
-   *   - source (string): The internal system path.
-   *   - alias (string): The URL alias.
-   *   - pid (int): Unique path alias identifier.
-   *   - langcode (string): The language code of the alias.
-   */
-  public function load($conditions);
-
-  /**
-   * Deletes a URL alias.
-   *
-   * @param array $conditions
-   *   An array of criteria.
-   */
-  public function delete($conditions);
+interface AliasStorageInterface extends EntityStorageInterface{
 
   /**
    * Pre-loads path alias information for a given list of source paths.
diff --git a/core/lib/Drupal/Core/Path/AliasStorageSchema.php b/core/lib/Drupal/Core/Path/AliasStorageSchema.php
new file mode 100644
index 0000000..8974c39
--- /dev/null
+++ b/core/lib/Drupal/Core/Path/AliasStorageSchema.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Path\AliasStorageSchema.
+ */
+
+namespace Drupal\Core\Path;
+
+use Drupal\Core\Entity\ContentEntityTypeInterface;
+use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;
+
+/**
+ * Defines the alias schema handler.
+ */
+class AliasStorageSchema extends SqlContentEntityStorageSchema {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) {
+    $schema = parent::getEntitySchema($entity_type, $reset);
+
+    $schema['alias_field_data']['indexes'] += array(
+      'alias_langcode_pid' => array('alias', 'langcode', 'aid'),
+      'path_langcode_pid' => array('path', 'langcode', 'aid'),
+    );
+
+    return $schema;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Path/AliasWhitelist.php b/core/lib/Drupal/Core/Path/AliasWhitelist.php
index 394dfa2..0754fdb 100644
--- a/core/lib/Drupal/Core/Path/AliasWhitelist.php
+++ b/core/lib/Drupal/Core/Path/AliasWhitelist.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Cache\CacheCollector;
-use Drupal\Core\Database\Connection;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\State\StateInterface;
 use Drupal\Core\Lock\LockBackendInterface;
 
@@ -26,11 +26,11 @@ class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
   protected $state;
 
   /**
-   * The Path CRUD service.
+   * The entity manager service.
    *
-   * @var \Drupal\Core\Path\AliasStorageInterface
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $aliasStorage;
+  protected $entityManager;
 
   /**
    * Constructs an AliasWhitelist object.
@@ -43,13 +43,13 @@ class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
    *   The lock backend.
    * @param \Drupal\Core\State\StateInterface $state
    *   The state keyvalue store.
-   * @param \Drupal\Core\Path\AliasStorageInterface $alias_storage
-   *   The alias storage service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    */
-  public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, StateInterface $state, AliasStorageInterface $alias_storage) {
+  public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, StateInterface $state, EntityManagerInterface $entity_manager) {
     parent::__construct($cid, $cache, $lock);
     $this->state = $state;
-    $this->aliasStorage = $alias_storage;
+    $this->entityManager = $entity_manager;
   }
 
   /**
@@ -107,7 +107,7 @@ public function get($offset) {
    * {@inheritdoc}
    */
   public function resolveCacheMiss($root) {
-    $exists = $this->aliasStorage->pathHasMatchingAlias($root);
+    $exists = $this->entityManager->getStorage('alias')->pathHasMatchingAlias($root);
     $this->storage[$root] = $exists;
     $this->persist($root);
     if ($exists) {
diff --git a/core/lib/Drupal/Core/Path/Entity/Alias.php b/core/lib/Drupal/Core/Path/Entity/Alias.php
new file mode 100644
index 0000000..15b4618
--- /dev/null
+++ b/core/lib/Drupal/Core/Path/Entity/Alias.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Path\Entity\Alias.
+ */
+
+namespace Drupal\Core\Path\Entity;
+
+use Drupal\Core\Entity\ContentEntityBase;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Path\AliasInterface;
+
+/**
+ * Defines the alias entityclass.
+ * // TODO: Should this live in Path.module (permission, routes)?
+ *
+ * @ContentEntityType(
+ *   id = "alias",
+ *   label = @Translation("Path alias"),
+ *   handlers = {
+ *     "storage" = "Drupal\Core\Path\AliasStorage",
+ *     "storage_schema" = "Drupal\Core\Path\AliasStorageSchema",
+ *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
+ *     "access" = "Drupal\Core\Entity\EntityAccessControlHandler",
+ *     "form" = {
+ *       "default" = "Drupal\media_entity\MediaForm",
+ *       "delete" = "Drupal\media_entity\Form\MediaDeleteForm",
+ *       "edit" = "Drupal\media_entity\MediaForm"
+ *     },
+ *     "translation" = "Drupal\content_translation\ContentTranslationHandler"
+ *   },
+ *   base_table = "alias",
+ *   data_table = "alias_field_data",
+ *   fieldable = TRUE,
+ *   translatable = TRUE,
+ *   render_cache = FALSE,
+ *   entity_keys = {
+ *     "id" = "aid",
+ *     "label" = "alias",
+ *     "uuid" = "uuid"
+ *   },
+ *   permission_granularity = "entity_type",
+ *   admin_permission = "administer url aliases",
+ *   links = {
+ *     "canonical" = "alias.view",
+ *     "delete-form" = "alias.delete_confirm",
+ *     "edit-form" = "alias.edit",
+ *   }
+ * )
+ */
+class Alias extends ContentEntityBase implements AliasInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    $fields['aid'] = BaseFieldDefinition::create('integer')
+      ->setLabel(t('Alias ID'))
+      ->setDescription(t('The alias ID.'))
+      ->setReadOnly(TRUE)
+      ->setSetting('unsigned', TRUE);
+
+    $fields['uuid'] = BaseFieldDefinition::create('uuid')
+      ->setLabel(t('UUID'))
+      ->setDescription(t('The alias UUID.'))
+      ->setReadOnly(TRUE);
+
+    $fields['path'] = BaseFieldDefinition::create('string')
+      ->setLabel(t('Path'))
+      ->setDescription(t('The path that this alias belongs to.'))
+      ->setRequired(TRUE)
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
+      ->setDefaultValue('')
+      ->setSetting('max_length', 255);
+
+    $fields['alias'] = BaseFieldDefinition::create('string')
+      ->setLabel(t('Alias'))
+      ->setDescription(t('The alias used with this path.'))
+      ->setRequired(TRUE)
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
+      ->setDefaultValue('')
+      ->setSetting('max_length', 255);
+
+    $fields['langcode'] = BaseFieldDefinition::create('language')
+      ->setLabel(t('Language code'))
+      ->setDescription(t('The alias language code.'))
+      ->setRevisionable(TRUE);
+
+    return $fields;
+  }
+
+}
diff --git a/core/modules/ckeditor/src/Tests/CKEditorPluginManagerTest.php b/core/modules/ckeditor/src/Tests/CKEditorPluginManagerTest.php
index d373e1a..94489ce 100644
--- a/core/modules/ckeditor/src/Tests/CKEditorPluginManagerTest.php
+++ b/core/modules/ckeditor/src/Tests/CKEditorPluginManagerTest.php
@@ -34,9 +34,6 @@ class CKEditorPluginManagerTest extends DrupalUnitTestBase {
   protected function setUp() {
     parent::setUp();
 
-    // Install the Filter module.
-    $this->installSchema('system', 'url_alias');
-
     // Create text format, associate CKEditor.
     $filtered_html_format = entity_create('filter_format', array(
       'format' => 'filtered_html',
diff --git a/core/modules/ckeditor/src/Tests/CKEditorTest.php b/core/modules/ckeditor/src/Tests/CKEditorTest.php
index b2c70aa..efbb7c6 100644
--- a/core/modules/ckeditor/src/Tests/CKEditorTest.php
+++ b/core/modules/ckeditor/src/Tests/CKEditorTest.php
@@ -42,9 +42,6 @@ class CKEditorTest extends DrupalUnitTestBase {
   protected function setUp() {
     parent::setUp();
 
-    // Install the Filter module.
-    $this->installSchema('system', 'url_alias');
-
     // Create text format, associate CKEditor.
     $filtered_html_format = entity_create('filter_format', array(
       'format' => 'filtered_html',
diff --git a/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php b/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
index 1b723ce..1ea674f 100644
--- a/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
+++ b/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
@@ -79,8 +79,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // @todo This should be taken care of by the Path module.
     if (\Drupal::moduleHandler()->moduleExists('path')) {
       $path = $this->entity->getSystemPath();
-      $conditions = array('source' => $path, 'langcode' => $this->language->id);
-      \Drupal::service('path.alias_storage')->delete($conditions);
+
+      $aid = reset(\Drupal::entityQuery('alias')
+        ->condition('path', $path)
+        ->condition('langcode', $this->language->id)
+        ->execute());
+
+      \Drupal::entityManager()->getStorage('alias')->delete(array($aid));
     }
 
     $form_state->setRedirectUrl($this->getCancelUrl());
diff --git a/core/modules/editor/src/Tests/EditorManagerTest.php b/core/modules/editor/src/Tests/EditorManagerTest.php
index b251f48..9420df9 100644
--- a/core/modules/editor/src/Tests/EditorManagerTest.php
+++ b/core/modules/editor/src/Tests/EditorManagerTest.php
@@ -34,9 +34,6 @@ class EditorManagerTest extends DrupalUnitTestBase {
   protected function setUp() {
     parent::setUp();
 
-    // Install the Filter module.
-    $this->installSchema('system', 'url_alias');
-
     // Add text formats.
     $filtered_html_format = entity_create('filter_format', array(
       'format' => 'filtered_html',
diff --git a/core/modules/editor/src/Tests/QuickEditIntegrationTest.php b/core/modules/editor/src/Tests/QuickEditIntegrationTest.php
index ee43da0..78623a9 100644
--- a/core/modules/editor/src/Tests/QuickEditIntegrationTest.php
+++ b/core/modules/editor/src/Tests/QuickEditIntegrationTest.php
@@ -67,9 +67,6 @@ class QuickEditIntegrationTest extends QuickEditTestBase {
   protected function setUp() {
     parent::setUp();
 
-    // Install the Filter module.
-    $this->installSchema('system', 'url_alias');
-
     // Create a field.
     $this->field_name = 'field_textarea';
     $this->createFieldWithStorage(
diff --git a/core/modules/filter/src/Tests/FilterDefaultConfigTest.php b/core/modules/filter/src/Tests/FilterDefaultConfigTest.php
index 79a1160..04e0894 100644
--- a/core/modules/filter/src/Tests/FilterDefaultConfigTest.php
+++ b/core/modules/filter/src/Tests/FilterDefaultConfigTest.php
@@ -20,11 +20,7 @@ class FilterDefaultConfigTest extends DrupalUnitTestBase {
 
   protected function setUp() {
     parent::setUp();
-
-    // Drupal\filter\FilterPermissions::permissions() calls into url() to output
-    // a link in the description.
-    $this->installSchema('system', 'url_alias');
-
+    
     $this->installEntitySchema('user');
 
     // Install filter_test module, which ships with custom default format.
diff --git a/core/modules/hal/src/Tests/NormalizerTestBase.php b/core/modules/hal/src/Tests/NormalizerTestBase.php
index c03167a..09e7ba9 100644
--- a/core/modules/hal/src/Tests/NormalizerTestBase.php
+++ b/core/modules/hal/src/Tests/NormalizerTestBase.php
@@ -61,7 +61,7 @@
    */
   protected function setUp() {
     parent::setUp();
-    $this->installSchema('system', array('url_alias', 'router'));
+    $this->installSchema('system', 'router');
     $this->installEntitySchema('user');
     $this->installEntitySchema('entity_test');
     $this->installConfig(array('field', 'language'));
diff --git a/core/modules/link/src/Tests/LinkFieldTest.php b/core/modules/link/src/Tests/LinkFieldTest.php
index c596c53..0986546 100644
--- a/core/modules/link/src/Tests/LinkFieldTest.php
+++ b/core/modules/link/src/Tests/LinkFieldTest.php
@@ -98,7 +98,12 @@ function testURLValidation() {
     $this->assertRaw('placeholder="http://example.com"');
 
     // Create a path alias.
-    \Drupal::service('path.alias_storage')->save('admin', 'a/path/alias');
+    \Drupal::service('entity.manager')->getStorage('alias')->create(
+      array(
+        'path' => 'admin',
+        'alias' => 'a/path/alias',
+      )
+    )->save();
     // Define some valid URLs.
     $valid_external_entries = array(
       'http://www.example.com/',
diff --git a/core/modules/locale/src/Tests/LocalePathTest.php b/core/modules/locale/src/Tests/LocalePathTest.php
index ae4b9db..675ea0c 100644
--- a/core/modules/locale/src/Tests/LocalePathTest.php
+++ b/core/modules/locale/src/Tests/LocalePathTest.php
@@ -73,7 +73,7 @@ public function testPathLanguageConfiguration() {
     $path = 'admin/config/search/path/add';
     $english_path = $this->randomMachineName(8);
     $edit = array(
-      'source'   => 'node/' . $node->id(),
+      'path'   => 'node/' . $node->id(),
       'alias'    => $english_path,
       'langcode' => 'en',
     );
@@ -82,7 +82,7 @@ public function testPathLanguageConfiguration() {
     // Create a path alias in new custom language.
     $custom_language_path = $this->randomMachineName(8);
     $edit = array(
-      'source'   => 'node/' . $node->id(),
+      'path'   => 'node/' . $node->id(),
       'alias'    => $custom_language_path,
       'langcode' => $langcode,
     );
@@ -100,39 +100,49 @@ public function testPathLanguageConfiguration() {
     $custom_path = $this->randomMachineName(8);
 
     // Check priority of language for alias by source path.
+    /** @var $alias_storage \Drupal\Core\Path\AliasStorageInterface */
+    $alias_storage = $this->container->get('entity.manager')->getStorage('alias');
     $edit = array(
-      'source'   => 'node/' . $node->id(),
+      'path'   => 'node/' . $node->id(),
       'alias'    => $custom_path,
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
     );
-    $this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
+    $alias = $alias_storage->create(
+      array(
+        'path' => $edit['path'],
+        'alias' => $edit['alias'],
+        'langcode' => $edit['langcode'],
+      )
+    );
     $lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $node->id(), 'en');
     $this->assertEqual($english_path, $lookup_path, 'English language alias has priority.');
     // Same check for language 'xx'.
     $lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $node->id(), $prefix);
     $this->assertEqual($custom_language_path, $lookup_path, 'Custom language alias has priority.');
-    $this->container->get('path.alias_storage')->delete($edit);
+    $alias->delete();
 
     // Create language nodes to check priority of aliases.
     $first_node = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1, 'langcode' => 'en'));
     $second_node = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED));
 
     // Assign a custom path alias to the first node with the English language.
-    $edit = array(
-      'source'   => 'node/' . $first_node->id(),
-      'alias'    => $custom_path,
-      'langcode' => $first_node->language()->id,
-    );
-    $this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
+    $alias_storage->create(
+      array(
+        'path' => 'node/' . $first_node->id(),
+        'alias' => $custom_path,
+        'langcode' => $first_node->language()->id,
+      )
+    )->save();
 
     // Assign a custom path alias to second node with
     // LanguageInterface::LANGCODE_NOT_SPECIFIED.
-    $edit = array(
-      'source'   => 'node/' . $second_node->id(),
-      'alias'    => $custom_path,
-      'langcode' => $second_node->language()->id,
-    );
-    $this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
+    $alias_storage->create(
+      array(
+        'path' => 'node/' . $second_node->id(),
+        'alias' => $custom_path,
+        'langcode' => $second_node->language()->id,
+      )
+    )->save();
 
     // Test that both node titles link to our path alias.
     $this->drupalGet('admin/content');
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/UrlAlias.php b/core/modules/migrate/src/Plugin/migrate/destination/UrlAlias.php
index 6312198..b386d99 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/UrlAlias.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/UrlAlias.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\migrate\Plugin\migrate\destination;
 
-use Drupal\Core\Path\AliasStorage;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\migrate\Entity\MigrationInterface;
 use Drupal\migrate\Row;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -21,11 +21,11 @@
 class UrlAlias extends DestinationBase implements ContainerFactoryPluginInterface {
 
   /**
-   * The alias storage service.
+   * The entity manager service.
    *
-   * @var \Drupal\Core\Path\AliasStorage $aliasStorage
+   * @var \Drupal\Core\Entity\EntityManagerInterface
    */
-  protected $aliasStorage;
+  protected $entityManager;
 
   /**
    * Constructs an entity destination plugin.
@@ -38,12 +38,12 @@ class UrlAlias extends DestinationBase implements ContainerFactoryPluginInterfac
    *   The plugin implementation definition.
    * @param MigrationInterface $migration
    *   The migration.
-   * @param \Drupal\Core\Path\AliasStorage $alias_storage
-   *   The alias storage service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, AliasStorage $alias_storage) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityManagerInterface $entity_manager) {
     parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
-    $this->aliasStorage = $alias_storage;
+    $this->entityManager = $entity_manager;
   }
 
   /**
@@ -55,7 +55,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $plugin_id,
       $plugin_definition,
       $migration,
-      $container->get('path.alias_storage')
+      $container->get('entity.manager')
     );
   }
 
@@ -63,22 +63,39 @@ public static function create(ContainerInterface $container, array $configuratio
    * {@inheritdoc}
    */
   public function import(Row $row, array $old_destination_id_values = array()) {
+    if ($old_destination_id_values) {
+      /** @var \Drupal\Core\Path\AliasInterface $alias */
+      $alias = $this->entityManager
+        ->getStorage('alias')
+        ->load($old_destination_id_values[0]);
 
-    $path = $this->aliasStorage->save(
-      $row->getDestinationProperty('source'),
-      $row->getDestinationProperty('alias'),
-      $row->getDestinationProperty('langcode'),
-      $old_destination_id_values ? $old_destination_id_values[0] : NULL
-    );
+      $alias->alias = $row->getDestinationProperty('alias');
+      $alias->path = $row->getDestinationProperty('path');
+      $alias->langcode = $row->getDestinationProperty('langcode');
+      $alias->save();
+    }
+    else {
+      /** @var \Drupal\Core\Path\AliasInterface $alias */
+      $alias = $this->entityManager
+        ->getStorage('alias')
+        ->create(
+          array(
+            'path' => $row->getDestinationProperty('path'),
+            'alias' => $row->getDestinationProperty('alias'),
+            'langcode' => $row->getDestinationProperty('langcode'),
+          )
+        );
+      $alias->save();
+    }
 
-    return array($path['pid']);
+    return array($alias->id());
   }
 
   /**
    * {@inheritdoc}
    */
   public function getIds() {
-    $ids['pid']['type'] = 'integer';
+    $ids['aid']['type'] = 'integer';
     return $ids;
   }
 
@@ -87,8 +104,8 @@ public function getIds() {
    */
   public function fields(MigrationInterface $migration = NULL) {
     return [
-      'pid' => 'The path id',
-      'source' => 'The source path.',
+      'aid' => 'The alias id',
+      'path' => 'The source path.',
       'alias' => 'The url alias.',
       'langcode' => 'The language code for the url.',
     ];
diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_url_alias.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_url_alias.yml
index 39d3234..871170b 100644
--- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_url_alias.yml
+++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_url_alias.yml
@@ -6,7 +6,7 @@ source:
   plugin: d6_url_alias
 
 process:
-  source: src
+  path: src
   alias: dst
   langcode: language
 
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php
index 8449cba..4905c8c 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateUrlAliasTest.php
@@ -39,21 +39,22 @@ protected function setUp() {
   public function testUrlAlias() {
     $migration = entity_load('migration', 'd6_url_alias');
     // Test that the field exists.
-    $conditions = array(
-      'source' => 'node/1',
-      'alias' => 'alias-one',
-      'langcode' => 'en',
-    );
-    $path = \Drupal::service('path.alias_storage')->load($conditions);
-    $this->assertNotNull($path, "Path alias for node/1 successfully loaded.");
-    $this->assertEqual(array(1), $migration->getIdMap()->lookupDestinationID(array($path['pid'])), "Test IdMap");
-    $conditions = array(
-      'source' => 'node/2',
-      'alias' => 'alias-two',
-      'langcode' => 'en',
-    );
-    $path = \Drupal::service('path.alias_storage')->load($conditions);
-    $this->assertNotNull($path, "Path alias for node/2 successfully loaded.");
+    $aids = \Drupal::entityQuery('alias')
+      ->condition('alias', 'alias-one')
+      ->condition('path', 'node/1')
+      ->condition('langcode', 'en')
+      ->execute();
+
+    $this->assertTrue((bool) $aids, "Path alias for node/1 successfully loaded.");
+    $alias = \Drupal::entityManager()->getStorage('alias')->load(reset($aids));
+    $this->assertEqual(array(1), $migration->getIdMap()->lookupDestinationID(array($alias->id())), "Test IdMap");
+    $aids = \Drupal::entityQuery('alias')
+      ->condition('alias', 'alias-two')
+      ->condition('path', 'node/2')
+      ->condition('langcode', 'en')
+      ->execute();
+    $this->assertTrue((bool) $aids, "Path alias for node/2 successfully loaded.");
+    $alias = \Drupal::entityManager()->getStorage('alias')->load(reset($aids));
 
     // Test that we can re-import using the UrlAlias destination.
     Database::getConnection('default', 'migrate')
@@ -69,8 +70,8 @@ public function testUrlAlias() {
     $executable = new MigrateExecutable($migration, $this);
     $executable->import();
 
-    $path = \Drupal::service('path.alias_storage')->load(array('pid' => $path['pid']));
-    $this->assertEqual($path['alias'], 'new-url-alias');
+    $alias = \Drupal::entityManager()->getStorage('alias')->load($alias->id());
+    $this->assertEqual($alias->get('alias')->value, 'new-url-alias');
   }
 
 }
diff --git a/core/modules/path/path.api.php b/core/modules/path/path.api.php
deleted file mode 100644
index 04e1fb3..0000000
--- a/core/modules/path/path.api.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-/**
- * @file
- * Hooks provided by the Path module.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Respond to a path being inserted.
- *
- * @param array $path
- *   The array structure is identical to that of the return value of
- *   \Drupal\Core\Path\PathInterface::save().
- *
- * @see \Drupal\Core\Path\PathInterface::save()
- */
-function hook_path_insert($path) {
-  db_insert('mytable')
-    ->fields(array(
-      'alias' => $path['alias'],
-      'pid' => $path['pid'],
-    ))
-    ->execute();
-}
-
-/**
- * Respond to a path being updated.
- *
- * @param array $path
- *   The array structure is identical to that of the return value of
- *   \Drupal\Core\Path\PathInterface::save().
- *
- * @see \Drupal\Core\Path\PathInterface::save()
- */
-function hook_path_update($path) {
-  if ($path['alias'] != $path['original']['alias']) {
-    db_update('mytable')
-      ->fields(array('alias' => $path['alias']))
-      ->condition('pid', $path['pid'])
-      ->execute();
-  }
-}
-
-/**
- * Respond to a path being deleted.
- *
- * @param array $path
- *   The array structure is identical to that of the return value of
- *   \Drupal\Core\Path\PathInterface::save().
- *
- * @see \Drupal\Core\Path\PathInterface::delete()
- */
-function hook_path_delete($path) {
-  db_delete('mytable')
-    ->condition('pid', $path['pid'])
-    ->execute();
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/core/modules/path/path.routing.yml b/core/modules/path/path.routing.yml
index d3e44c3..0635704 100644
--- a/core/modules/path/path.routing.yml
+++ b/core/modules/path/path.routing.yml
@@ -1,5 +1,5 @@
 path.delete:
-  path: '/admin/config/search/path/delete/{pid}'
+  path: '/admin/config/search/path/delete/{aid}'
   defaults:
     _form: '\Drupal\path\Form\DeleteForm'
     _title: 'Delete alias'
@@ -32,7 +32,7 @@ path.admin_add:
     _permission: 'administer url aliases'
 
 path.admin_edit:
-  path: '/admin/config/search/path/edit/{pid}'
+  path: '/admin/config/search/path/edit/{aid}'
   defaults:
     _title: 'Edit alias'
     _form: '\Drupal\path\Form\EditForm'
diff --git a/core/modules/path/src/Controller/PathController.php b/core/modules/path/src/Controller/PathController.php
index 6144b67..5556012 100644
--- a/core/modules/path/src/Controller/PathController.php
+++ b/core/modules/path/src/Controller/PathController.php
@@ -18,13 +18,6 @@
 class PathController extends ControllerBase {
 
   /**
-   * The path alias storage.
-   *
-   * @var \Drupal\Core\Path\AliasStorageInterface
-   */
-  protected $aliasStorage;
-
-  /**
    * The path alias manager.
    *
    * @var \Drupal\Core\Path\AliasManagerInterface
@@ -39,8 +32,7 @@ class PathController extends ControllerBase {
    * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
    *   The path alias manager.
    */
-  public function __construct(AliasStorageInterface $alias_storage, AliasManagerInterface $alias_manager) {
-    $this->aliasStorage = $alias_storage;
+  public function __construct(AliasManagerInterface $alias_manager) {
     $this->aliasManager = $alias_manager;
   }
 
@@ -49,7 +41,6 @@ public function __construct(AliasStorageInterface $alias_storage, AliasManagerIn
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('path.alias_storage'),
       $container->get('path.alias_manager')
     );
   }
@@ -59,7 +50,7 @@ public function adminOverview($keys) {
     $build['path_admin_filter_form'] = $this->formBuilder()->getForm('Drupal\path\Form\PathFilterForm', $keys);
     // Enable language column if language.module is enabled or if we have any
     // alias with a language.
-    $multilanguage = ($this->moduleHandler()->moduleExists('language') || $this->aliasStorage->languageAliasExists());
+    $multilanguage = ($this->moduleHandler()->moduleExists('language') || $this->entityManager()->getStorage('alias')->languageAliasExists());
 
     $header = array();
     $header[] = array('data' => $this->t('Alias'), 'field' => 'alias', 'sort' => 'asc');
@@ -71,14 +62,14 @@ public function adminOverview($keys) {
 
     $rows = array();
     $destination = drupal_get_destination();
-    foreach ($this->aliasStorage->getAliasesForAdminListing($header, $keys) as $data) {
+    foreach ($this->entityManager()->getStorage('alias')->getAliasesForAdminListing($header, $keys) as $data) {
       $row = array();
-      $row['data']['alias'] = l(truncate_utf8($data->alias, 50, FALSE, TRUE), $data->source, array(
+      $row['data']['alias'] = l(truncate_utf8($data->alias, 50, FALSE, TRUE), $data->path, array(
         'attributes' => array('title' => $data->alias),
       ));
-      $row['data']['source'] = l(truncate_utf8($data->source, 50, FALSE, TRUE), $data->source, array(
+      $row['data']['source'] = l(truncate_utf8($data->path, 50, FALSE, TRUE), $data->path, array(
         'alias' => TRUE,
-        'attributes' => array('title' => $data->source),
+        'attributes' => array('title' => $data->path),
       ));
       if ($multilanguage) {
         $row['data']['language_name'] = $this->languageManager()->getLanguageName($data->langcode);
@@ -89,7 +80,7 @@ public function adminOverview($keys) {
         'title' => $this->t('Edit'),
         'route_name' => 'path.admin_edit',
         'route_parameters' => array(
-          'pid' => $data->pid,
+          'aid' => $data->aid,
         ),
         'query' => $destination,
       );
@@ -97,7 +88,7 @@ public function adminOverview($keys) {
         'title' => $this->t('Delete'),
         'route_name' => 'path.delete',
         'route_parameters' => array(
-          'pid' => $data->pid,
+          'aid' => $data->aid,
         ),
         'query' => $destination,
       );
@@ -110,7 +101,7 @@ public function adminOverview($keys) {
 
       // If the system path maps to a different URL alias, highlight this table
       // row to let the user know of old aliases.
-      if ($data->alias != $this->aliasManager->getAliasByPath($data->source, $data->langcode)) {
+      if ($data->alias != $this->aliasManager->getAliasByPath($data->path, $data->langcode)) {
         $row['class'] = array('warning');
       }
 
diff --git a/core/modules/path/src/Form/AddForm.php b/core/modules/path/src/Form/AddForm.php
index aab238b..0787347 100644
--- a/core/modules/path/src/Form/AddForm.php
+++ b/core/modules/path/src/Form/AddForm.php
@@ -24,13 +24,12 @@ public function getFormId() {
   /**
    * {@inheritdoc}
    */
-  protected function buildPath($pid) {
-    return array(
-      'source' => '',
+  protected function buildPath($aid) {
+    return $this->entityManager->getStorage('alias')->create(array(
+      'path' => '',
       'alias' => '',
       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
-      'pid' => NULL,
-    );
+    ));
   }
 
 }
diff --git a/core/modules/path/src/Form/DeleteForm.php b/core/modules/path/src/Form/DeleteForm.php
index 80251dc..3eb5e44 100644
--- a/core/modules/path/src/Form/DeleteForm.php
+++ b/core/modules/path/src/Form/DeleteForm.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\path\Form;
 
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Path\AliasStorageInterface;
 use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -19,27 +19,27 @@
 class DeleteForm extends ConfirmFormBase {
 
   /**
-   * The alias storage service.
+   * The entity manager service.
    *
-   * @var AliasStorageInterface $path
+   * @var \Drupal\Core\Entity\EntityManagerInterface $entityManager
    */
-  protected $aliasStorage;
+  protected $entityManager;
 
   /**
    * The path alias being deleted.
    *
-   * @var array $pathAlias
+   * @var \Drupal\Core\Path\AliasInterface $pathAlias
    */
   protected $pathAlias;
 
   /**
    * Constructs a \Drupal\path\Form\DeleteForm object.
    *
-   * @param \Drupal\Core\Path\AliasStorageInterface $alias_storage
-   *   The alias storage service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    */
-  public function __construct(AliasStorageInterface $alias_storage) {
-    $this->aliasStorage = $alias_storage;
+  public function __construct(EntityManagerInterface $entity_manager) {
+    $this->entityManager = $entity_manager;
   }
 
   /**
@@ -47,7 +47,7 @@ public function __construct(AliasStorageInterface $alias_storage) {
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('path.alias_storage')
+      $container->get('entity.manager')
     );
   }
 
@@ -62,7 +62,7 @@ public function getFormId() {
    * Implements \Drupal\Core\Form\ConfirmFormBase::getQuestion().
    */
   public function getQuestion() {
-    return t('Are you sure you want to delete path alias %title?', array('%title' => $this->pathAlias['alias']));
+    return t('Are you sure you want to delete path alias %title?', array('%title' => $this->pathAlias->get('alias')->value));
   }
 
   /**
@@ -75,8 +75,8 @@ public function getCancelUrl() {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, $pid = NULL) {
-    $this->pathAlias = $this->aliasStorage->load(array('pid' => $pid));
+  public function buildForm(array $form, FormStateInterface $form_state, $aid = NULL) {
+    $this->pathAlias = $this->entityManager->getStorage('alias')->load($aid);
 
     $form = parent::buildForm($form, $form_state);
 
@@ -87,8 +87,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $this->aliasStorage->delete(array('pid' => $this->pathAlias['pid']));
-
+    $this->pathAlias->delete();
     $form_state->setRedirect('path.admin_overview');
   }
 
diff --git a/core/modules/path/src/Form/EditForm.php b/core/modules/path/src/Form/EditForm.php
index 95d5e20..412f1c0 100644
--- a/core/modules/path/src/Form/EditForm.php
+++ b/core/modules/path/src/Form/EditForm.php
@@ -26,20 +26,20 @@ public function getFormId() {
   /**
    * {@inheritdoc}
    */
-  protected function buildPath($pid) {
-    return $this->aliasStorage->load(array('pid' => $pid));
+  protected function buildPath($aid) {
+    return $this->entityManager->getStorage('alias')->load($aid);
   }
 
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, $pid = NULL) {
-    $form = parent::buildForm($form, $form_state, $pid);
+  public function buildForm(array $form, FormStateInterface $form_state, $aid = NULL) {
+    $form = parent::buildForm($form, $form_state, $aid);
 
-    $form['#title'] = String::checkPlain($this->path['alias']);
-    $form['pid'] = array(
+    $form['#title'] = String::checkPlain($this->alias->get('alias')->value);
+    $form['aid'] = array(
       '#type' => 'hidden',
-      '#value' => $this->path['pid'],
+      '#value' => $this->alias->id(),
     );
     $form['actions']['delete'] = array(
       '#type' => 'submit',
@@ -54,7 +54,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
    */
   public function deleteSubmit(array &$form, FormStateInterface $form_state) {
     $url = new Url('path.delete', array(
-      'pid' => $form_state->getValue('pid'),
+      'aid' => $form_state->getValue('aid'),
     ));
 
     if ($this->getRequest()->query->has('destination')) {
diff --git a/core/modules/path/src/Form/PathFormBase.php b/core/modules/path/src/Form/PathFormBase.php
index 8564156..cdb783d 100644
--- a/core/modules/path/src/Form/PathFormBase.php
+++ b/core/modules/path/src/Form/PathFormBase.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\path\Form;
 
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
@@ -21,18 +22,18 @@
 abstract class PathFormBase extends FormBase {
 
   /**
-   * An array containing the path ID, source, alias, and language code.
+   * Path alias object
    *
-   * @var array
+   * @var \Drupal\Core\Path\AliasInterface
    */
-  protected $path;
+  protected $alias;
 
   /**
-   * The path alias storage.
+   * The entity manager service.
    *
-   * @var \Drupal\Core\Path\AliasStorageInterface
+   * @var \Drupal\Core\Entity\EntityManagerInterface $entityManager
    */
-  protected $aliasStorage;
+  protected $entityManager;
 
   /**
    * The path alias manager.
@@ -51,15 +52,15 @@
   /**
    * Constructs a new PathController.
    *
-   * @param \Drupal\Core\Path\AliasStorageInterface $alias_storage
-   *   The path alias storage.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
    *   The path alias manager.
    * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
    *   The path validator.
    */
-  public function __construct(AliasStorageInterface $alias_storage, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator) {
-    $this->aliasStorage = $alias_storage;
+  public function __construct(EntityManagerInterface $entity_manager, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator) {
+    $this->entityManager = $entity_manager;
     $this->aliasManager = $alias_manager;
     $this->pathValidator = $path_validator;
   }
@@ -69,29 +70,29 @@ public function __construct(AliasStorageInterface $alias_storage, AliasManagerIn
    */
   public static function create(ContainerInterface $container) {
     return new static(
-      $container->get('path.alias_storage'),
+      $container->get('entity.manager'),
       $container->get('path.alias_manager'),
       $container->get('path.validator')
     );
   }
 
   /**
-   * Builds the path used by the form.
+   * Builds the alias object used by the form.
    *
-   * @param int|null $pid
-   *   Either the unique path ID, or NULL if a new one is being created.
+   * @param int|null $aid
+   *   Either the unique alias ID, or NULL if a new one is being created.
    */
-  abstract protected function buildPath($pid);
+  abstract protected function buildPath($aid);
 
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, $pid = NULL) {
-    $this->path = $this->buildPath($pid);
-    $form['source'] = array(
+  public function buildForm(array $form, FormStateInterface $form_state, $aid = NULL) {
+    $this->alias = $this->buildPath($aid);
+    $form['path'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Existing system path'),
-      '#default_value' => $this->path['source'],
+      '#default_value' => $this->alias->get('path')->value,
       '#maxlength' => 255,
       '#size' => 45,
       '#description' => $this->t('Specify the existing path you wish to alias. For example: node/28, forum/1, taxonomy/term/1.'),
@@ -101,7 +102,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
     $form['alias'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Path alias'),
-      '#default_value' => $this->path['alias'],
+      '#default_value' => $this->alias->get('alias')->value,
       '#maxlength' => 255,
       '#size' => 45,
       '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "about" when writing an about page. Use a relative path and don\'t add a trailing slash or the URL alias won\'t work.'),
@@ -123,7 +124,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
         '#options' => $language_options,
         '#empty_value' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
         '#empty_option' => $this->t('- None -'),
-        '#default_value' => $this->path['langcode'],
+        '#default_value' => $this->alias->get('langcode')->value,
         '#weight' => -10,
         '#description' => $this->t('A path alias set for a specific language will always be used when displaying this page in that language, and takes precedence over path aliases set as <em>- None -</em>.'),
       );
@@ -131,7 +132,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
     else {
       $form['langcode'] = array(
         '#type' => 'value',
-        '#value' => $this->path['langcode']
+        '#value' => $this->alias->get('langcode')->value
       );
     }
 
@@ -148,18 +149,18 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $source = &$form_state->getValue('source');
-    $source = $this->aliasManager->getPathByAlias($source);
+    $path = &$form_state->getValue('path');
+    $path = $this->aliasManager->getPathByAlias($path);
     $alias = $form_state->getValue('alias');
     // Language is only set if language.module is enabled, otherwise save for all
     // languages.
     $langcode = $form_state->getValue('langcode', LanguageInterface::LANGCODE_NOT_SPECIFIED);
 
-    if ($this->aliasStorage->aliasExists($alias, $langcode, $source)) {
+    if ($this->entityManager->getStorage('alias')->aliasExists($alias, $langcode, $path)) {
       $form_state->setErrorByName('alias', t('The alias %alias is already in use in this language.', array('%alias' => $alias)));
     }
-    if (!$this->pathValidator->isValid($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)));
+    if (!$this->pathValidator->isValid($path)) {
+      $form_state->setErrorByName('path', t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $source)));
     }
   }
 
@@ -170,15 +171,31 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // Remove unnecessary values.
     $form_state->cleanValues();
 
-    $pid = $form_state->getValue('pid', 0);
-    $source = &$form_state->getValue('source');
-    $source = $this->aliasManager->getPathByAlias($source);
-    $alias = $form_state->getValue('alias');
+    $aid = $form_state->getValue('aid', 0);
+    $path = &$form_state->getValue('path');
+    $path = $this->aliasManager->getPathByAlias($path);
+    $alias_value = $form_state->getValue('alias');
     // Language is only set if language.module is enabled, otherwise save for all
     // languages.
     $langcode = $form_state->getValue('langcode', LanguageInterface::LANGCODE_NOT_SPECIFIED);
 
-    $this->aliasStorage->save($source, $alias, $langcode, $pid);
+    if (empty($aid)) {
+      $alias = $this->entityManager->getStorage('alias')->create(
+        array(
+          'alias' => $alias_value,
+          'path' => $path,
+          'langcode' => $langcode,
+        )
+      );
+      $alias->save();
+    }
+    else {
+      $alias = $this->entityManager->getStorage('alias')->load($aid);
+      $alias->path = $path;
+      $alias->alias = $alias_value;
+      $alias->langcode = $langcode;
+      $alias->save();
+    }
 
     drupal_set_message($this->t('The alias has been saved.'));
     $form_state->setRedirect('path.admin_overview');
diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
index cff3fa6..bf18cb3 100644
--- a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
+++ b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
@@ -33,8 +33,8 @@ class PathItem extends FieldItemBase {
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
     $properties['alias'] = DataDefinition::create('string')
       ->setLabel(t('Path alias'));
-    $properties['pid'] = DataDefinition::create('string')
-      ->setLabel(t('Path id'));
+    $properties['aid'] = DataDefinition::create('string')
+      ->setLabel(t('Alias ID'));
     return $properties;
   }
 
@@ -59,8 +59,16 @@ public function insert() {
     if ($this->alias) {
       $entity = $this->getEntity();
 
-      if ($path = \Drupal::service('path.alias_storage')->save($entity->getSystemPath(), $this->alias, $this->getLangcode())) {
-        $this->pid = $path['pid'];
+      $alias = \Drupal::entityManager()->getStorage('alias')->create(
+        array(
+          'path' => $entity->getSystemPath(),
+          'alias' => $this->alias,
+          'langcode' => $this->getLangcode(),
+        )
+      );
+
+      if ($alias->save()) {
+        $this->aid = $alias->id();
       }
     }
   }
@@ -70,14 +78,27 @@ public function insert() {
    */
   public function update() {
     // Delete old alias if user erased it.
-    if ($this->pid && !$this->alias) {
-      \Drupal::service('path.alias_storage')->delete(array('pid' => $this->pid));
+    if ($this->aid && !$this->alias) {
+      $alias = \Drupal::entityManager()->getStorage('alias')->load($this->aid);
+      $alias->delete();
     }
     // Only save a non-empty alias.
     elseif ($this->alias) {
       $entity = $this->getEntity();
-
-      \Drupal::service('path.alias_storage')->save($entity->getSystemPath(), $this->alias, $this->getLangcode(), $this->pid);
+      if ($this->aid) {
+        $alias = \Drupal::entityManager()
+          ->getStorage('alias')
+          ->load($this->aid);
+      }
+      else {
+        $alias = \Drupal::entityManager()
+          ->getStorage('alias')
+          ->create();
+      }
+      $alias->path = $entity->getSystemPath();
+      $alias->alias = $this->alias;
+      $alias->langcode = $this->getLangcode();
+      $alias->save();
     }
   }
 
@@ -86,8 +107,7 @@ public function update() {
    */
   public function delete() {
     // Delete all aliases associated with this entity.
-    $entity = $this->getEntity();
-    \Drupal::service('path.alias_storage')->delete(array('source' => $entity->getSystemPath()));
+    \Drupal::entityManager()->getStorage('alias')->delete(array($this->aid));
   }
 
   /**
diff --git a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
index 513aee4..f432b31 100644
--- a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
+++ b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
@@ -31,23 +31,21 @@ class PathWidget extends WidgetBase {
    */
   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
     $entity = $items->getEntity();
-    $path = array();
+    $alias = NULL;
     if (!$entity->isNew()) {
-      $conditions = array('source' => $entity->getSystemPath());
+      $query = \Drupal::entityQuery('alias')
+        ->condition('path', $entity->getSystemPath());
       if ($items->getLangcode() != LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-        $conditions['langcode'] = $items->getLangcode();
+        $query->condition('langcode', $items->getLangcode());
       }
-      $path = \Drupal::service('path.alias_storage')->load($conditions);
-      if ($path === FALSE) {
-        $path = array();
+      $aids = $query->execute();
+
+      if ($aids) {
+        $alias = reset($aids);
+        /** @var $alias \Drupal\Core\Path\AliasInterface */
+        $alias = \Drupal::entityManager()->getStorage('alias')->load($alias);
       }
     }
-    $path += array(
-      'pid' => NULL,
-      'source' => !$entity->isNew() ? $entity->getSystemPath() : NULL,
-      'alias' => '',
-      'langcode' => $items->getLangcode(),
-    );
 
     $element += array(
       '#element_validate' => array(array(get_class($this), 'validateFormElement')),
@@ -55,22 +53,22 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $element['alias'] = array(
       '#type' => 'textfield',
       '#title' => $element['#title'],
-      '#default_value' => $path['alias'],
+      '#default_value' => empty($alias) ? '' : $alias->get('alias')->value,
       '#required' => $element['#required'],
       '#maxlength' => 255,
       '#description' => $this->t('The alternative URL for this content. Use a relative path without a trailing slash. For example, enter "about" for the about page.'),
     );
-    $element['pid'] = array(
+    $element['aid'] = array(
       '#type' => 'value',
-      '#value' => $path['pid'],
+      '#value' => empty($alias) ? NULL : $alias->id(),
     );
-    $element['source'] = array(
+    $element['path'] = array(
       '#type' => 'value',
-      '#value' => $path['source'],
+      '#value' => empty($alias) ? (!$entity->isNew() ? $entity->getSystemPath() : NULL) : $alias->path->value,
     );
     $element['langcode'] = array(
       '#type' => 'value',
-      '#value' => $path['langcode'],
+      '#value' => empty($alias) ? $items->getLangcode() : $alias->langcode->value,
     );
     return $element;
   }
@@ -90,7 +88,7 @@ public static function validateFormElement(array &$element, FormStateInterface $
       $form_state->setValueForElement($element['alias'], $alias);
 
       // Validate that the submitted alias does not exist yet.
-      $is_exists = \Drupal::service('path.alias_storage')->aliasExists($alias, $element['langcode']['#value'], $element['source']['#value']);
+      $is_exists = \Drupal::entityManager()->getStorage('alias')->aliasExists($alias, $element['langcode']['#value'], $element['path']['#value']);
       if ($is_exists) {
         $form_state->setError($element, t('The alias is already in use.'));
       }
diff --git a/core/modules/path/src/Tests/PathAdminTest.php b/core/modules/path/src/Tests/PathAdminTest.php
index ef1d3e7..f081271 100644
--- a/core/modules/path/src/Tests/PathAdminTest.php
+++ b/core/modules/path/src/Tests/PathAdminTest.php
@@ -40,14 +40,14 @@ public function testPathFiltering() {
     // Create aliases.
     $alias1 = $this->randomMachineName(8);
     $edit = array(
-      'source' => 'node/' . $node1->id(),
+      'path' => 'node/' . $node1->id(),
       'alias' => $alias1,
     );
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
     $alias2 = $this->randomMachineName(8);
     $edit = array(
-      'source' => 'node/' . $node2->id(),
+      'path' => 'node/' . $node2->id(),
       'alias' => $alias2,
     );
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
diff --git a/core/modules/path/src/Tests/PathAliasTest.php b/core/modules/path/src/Tests/PathAliasTest.php
index 134f9d7..839cb3fd 100644
--- a/core/modules/path/src/Tests/PathAliasTest.php
+++ b/core/modules/path/src/Tests/PathAliasTest.php
@@ -39,7 +39,7 @@ function testPathCache() {
 
     // Create alias.
     $edit = array();
-    $edit['source'] = 'node/' . $node1->id();
+    $edit['path'] = 'node/' . $node1->id();
     $edit['alias'] = $this->randomMachineName(8);
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
@@ -52,13 +52,13 @@ function testPathCache() {
     // created.
     \Drupal::cache('data')->deleteAll();
     // Make sure the path is not converted to the alias.
-    $this->drupalGet($edit['source'], array('alias' => TRUE));
-    $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['source']), 'Cache entry was created.');
+    $this->drupalGet($edit['path'], array('alias' => TRUE));
+    $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['path']), 'Cache entry was created.');
 
     // Visit the alias for the node and confirm a cache entry is created.
     \Drupal::cache('data')->deleteAll();
     $this->drupalGet($edit['alias']);
-    $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' .  $edit['source']), 'Cache entry was created.');
+    $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' .  $edit['path']), 'Cache entry was created.');
   }
 
   /**
@@ -70,7 +70,7 @@ function testAdminAlias() {
 
     // Create alias.
     $edit = array();
-    $edit['source'] = 'node/' . $node1->id();
+    $edit['path'] = 'node/' . $node1->id();
     $edit['alias'] = $this->randomMachineName(8);
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
@@ -80,13 +80,13 @@ function testAdminAlias() {
     $this->assertResponse(200);
 
     // Change alias to one containing "exotic" characters.
-    $pid = $this->getPID($edit['alias']);
+    $aid = $this->getAID($edit['alias']);
 
     $previous = $edit['alias'];
     $edit['alias'] = "- ._~!$'\"()*@[]?&+%#,;=:" . // "Special" ASCII characters.
       "%23%25%26%2B%2F%3F" . // Characters that look like a percent-escaped string.
       "éøïвβ中國書۞"; // Characters from various non-ASCII alphabets.
-    $this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
+    $this->drupalPostForm('admin/config/search/path/edit/' . $aid, $edit, t('Save'));
 
     // Confirm that the alias works.
     $this->drupalGet($edit['alias']);
@@ -103,7 +103,7 @@ function testAdminAlias() {
     $node2 = $this->drupalCreateNode();
 
     // Set alias to second test node.
-    $edit['source'] = 'node/' . $node2->id();
+    $edit['path'] = 'node/' . $node2->id();
     // leave $edit['alias'] the same
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
@@ -111,7 +111,7 @@ function testAdminAlias() {
     $this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias'])), 'Attempt to move alias was rejected.');
 
     // Delete alias.
-    $this->drupalPostForm('admin/config/search/path/edit/' . $pid, array(), t('Delete'));
+    $this->drupalPostForm('admin/config/search/path/edit/' . $aid, array(), t('Delete'));
     $this->drupalPostForm(NULL, array(), t('Confirm'));
 
     // Confirm that the alias no longer works.
@@ -121,7 +121,7 @@ function testAdminAlias() {
 
     // Create a really long alias.
     $edit = array();
-    $edit['source'] = 'node/' . $node1->id();
+    $edit['path'] = 'node/' . $node1->id();
     $alias = $this->randomMachineName(128);
     $edit['alias'] = $alias;
     // The alias is shortened to 50 characters counting the elipsis.
@@ -192,16 +192,16 @@ function testNodeAlias() {
   }
 
   /**
-   * Returns the path ID.
+   * Returns the alias ID.
    *
    * @param $alias
    *   A string containing an aliased path.
    *
    * @return int
-   *   Integer representing the path ID.
+   *   Integer representing the alias ID.
    */
-  function getPID($alias) {
-    return db_query("SELECT pid FROM {url_alias} WHERE alias = :alias", array(':alias' => $alias))->fetchField();
+  function getAID($alias) {
+    return db_query("SELECT aid FROM {alias_field_data} WHERE alias = :alias", array(':alias' => $alias))->fetchField();
   }
 
   /**
diff --git a/core/modules/path/src/Tests/PathLanguageUiTest.php b/core/modules/path/src/Tests/PathLanguageUiTest.php
index ab33c0e..b6836fe 100644
--- a/core/modules/path/src/Tests/PathLanguageUiTest.php
+++ b/core/modules/path/src/Tests/PathLanguageUiTest.php
@@ -45,7 +45,7 @@ protected function setUp() {
   function testLanguageNeutralUrl() {
     $name = $this->randomMachineName(8);
     $edit = array();
-    $edit['source'] = 'admin/config/search/path';
+    $edit['path'] = 'admin/config/search/path';
     $edit['alias'] = $name;
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
 
@@ -59,7 +59,7 @@ function testLanguageNeutralUrl() {
   function testDefaultLanguageUrl() {
     $name = $this->randomMachineName(8);
     $edit = array();
-    $edit['source'] = 'admin/config/search/path';
+    $edit['path'] = 'admin/config/search/path';
     $edit['alias'] = $name;
     $edit['langcode'] = 'en';
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
@@ -74,7 +74,7 @@ function testDefaultLanguageUrl() {
   function testNonDefaultUrl() {
     $name = $this->randomMachineName(8);
     $edit = array();
-    $edit['source'] = 'admin/config/search/path';
+    $edit['path'] = 'admin/config/search/path';
     $edit['alias'] = $name;
     $edit['langcode'] = 'fr';
     $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
diff --git a/core/modules/quickedit/src/Tests/MetadataGeneratorTest.php b/core/modules/quickedit/src/Tests/MetadataGeneratorTest.php
index 32b3d26..3314ad2 100644
--- a/core/modules/quickedit/src/Tests/MetadataGeneratorTest.php
+++ b/core/modules/quickedit/src/Tests/MetadataGeneratorTest.php
@@ -127,8 +127,6 @@ public function testSimpleEntityType() {
    * Tests a field whose associated in-place editor generates custom metadata.
    */
   public function testEditorWithCustomMetadata() {
-    $this->installSchema('system', 'url_alias');
-
     $this->editorManager = $this->container->get('plugin.manager.quickedit.editor');
     $this->editorSelector = new EditorSelector($this->editorManager, $this->container->get('plugin.manager.field.formatter'));
     $this->metadataGenerator = new MetadataGenerator($this->accessChecker, $this->editorSelector, $this->editorManager);
diff --git a/core/modules/serialization/src/Tests/NormalizerTestBase.php b/core/modules/serialization/src/Tests/NormalizerTestBase.php
index 531c53d..73e0342 100644
--- a/core/modules/serialization/src/Tests/NormalizerTestBase.php
+++ b/core/modules/serialization/src/Tests/NormalizerTestBase.php
@@ -23,7 +23,6 @@ protected function setUp() {
 
     $this->installEntitySchema('entity_test_mulrev');
     $this->installEntitySchema('user');
-    $this->installSchema('system', array('url_alias'));
     $this->installConfig(array('field'));
 
     // Auto-create a field for testing.
diff --git a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
index 24c5550..bc09396 100644
--- a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
+++ b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
@@ -30,11 +30,14 @@ public function testShortcutLinkAdd() {
     $set = $this->set;
 
     // Create an alias for the node so we can test aliases.
-    $path = array(
-      'source' => 'node/' . $this->node->id(),
-      'alias' => $this->randomMachineName(8),
-    );
-    $this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
+    $alias = $this->container->get('entity.manager')->getStorage('alias')
+      ->create(
+        array(
+          'path' => $this->node->getSystemPath(),
+          'alias' => $this->randomMachineName(8),
+        )
+      );
+    $alias->save();
 
     // Create some paths to test.
     $test_cases = array(
@@ -43,7 +46,7 @@ public function testShortcutLinkAdd() {
       array('path' => 'admin', 'route_name' => 'system.admin'),
       array('path' => 'admin/config/system/site-information', 'route_name' => 'system.site_information_settings'),
       array('path' => 'node/' . $this->node->id() . '/edit', 'route_name' => 'entity.node.edit_form'),
-      array('path' => $path['alias'], 'route_name' => 'entity.node.canonical'),
+      array('path' => $alias->get('alias')->value, 'route_name' => 'entity.node.canonical'),
       array('path' => 'router_test/test2', 'route_name' => 'router_test.2'),
       array('path' => 'router_test/test3/value', 'route_name' => 'router_test.3'),
     );
diff --git a/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php b/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php
index 76e87f4..0c82ffd 100644
--- a/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php
@@ -19,11 +19,6 @@
  */
 class EntityAccessControlHandlerTest extends EntityLanguageTestBase  {
 
-  protected function setUp() {
-    parent::setUp();
-    $this->installSchema('system', 'url_alias');
-  }
-
   /**
    * Asserts entity access correctly grants or denies access.
    */
diff --git a/core/modules/system/src/Tests/Path/AliasTest.php b/core/modules/system/src/Tests/Path/AliasTest.php
index d91c59f..0674b0a 100644
--- a/core/modules/system/src/Tests/Path/AliasTest.php
+++ b/core/modules/system/src/Tests/Path/AliasTest.php
@@ -8,10 +8,11 @@
 namespace Drupal\system\Tests\Path;
 
 use Drupal\Core\Cache\MemoryCounterBackend;
-use Drupal\Core\Path\AliasStorage;
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Path\AliasManager;
 use Drupal\Core\Path\AliasWhitelist;
+use Drupal\language\Entity\ConfigurableLanguage;
 
 /**
  * Tests path alias CRUD and lookup functionality.
@@ -20,134 +21,212 @@
  */
 class AliasTest extends PathUnitTestBase {
 
+  public static $modules = array('language');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installConfig(array('language'));
+
+    $i = 0;
+    foreach (array('af', 'fr') as $langcode) {
+      $language = ConfigurableLanguage::createFromLangcode($langcode);
+      $language->set('weight', $i--);
+      $language->save();
+    }
+  }
+
   function testCRUD() {
     //Prepare database table.
     $connection = Database::getConnection();
-    $this->fixtures->createTables($connection);
-
-    //Create Path object.
-    $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
+    $this->fixtures->createTables($connection, $this->container->get('entity.manager'));
 
     $aliases = $this->fixtures->sampleUrlAliases();
 
     //Create a few aliases
     foreach ($aliases as $idx => $alias) {
-      $aliasStorage->save($alias['source'], $alias['alias'], $alias['langcode']);
-
-      $result = $connection->query('SELECT * FROM {url_alias} WHERE source = :source AND alias= :alias AND langcode = :langcode', array(':source' => $alias['source'], ':alias' => $alias['alias'], ':langcode' => $alias['langcode']));
+      $this->container->get('entity.manager')
+        ->getStorage('alias')
+        ->create(
+          array(
+            'path' => $alias['path'],
+            'alias' => $alias['alias'],
+            'langcode' => $alias['langcode']
+          )
+        )
+      ->save();
+
+      $result = $connection->query('SELECT * FROM {alias_field_data} WHERE path = :path AND alias= :alias AND langcode = :langcode', array(':path' => $alias['path'], ':alias' => $alias['alias'], ':langcode' => $alias['langcode']));
       $rows = $result->fetchAll();
 
       $this->assertEqual(count($rows), 1, format_string('Created an entry for %alias.', array('%alias' => $alias['alias'])));
 
       //Cache the pid for further tests.
-      $aliases[$idx]['pid'] = $rows[0]->pid;
+      $aliases[$idx]['aid'] = $rows[0]->aid;
     }
 
     //Load a few aliases
     foreach ($aliases as $alias) {
-      $pid = $alias['pid'];
-      $loadedAlias = $aliasStorage->load(array('pid' => $pid));
-      $this->assertEqual($loadedAlias, $alias, format_string('Loaded the expected path with pid %pid.', array('%pid' => $pid)));
+      $aid = $alias['aid'];
+      $loadedAlias = $this->container->get('entity.manager')
+        ->getStorage('alias')
+        ->load($alias['aid']);
+
+      $this->assertEqual($loadedAlias->get('alias')->value, $alias['alias'], format_string('Loaded the expected alias with aid %aid.', array('%aid' => $aid)));
+      $this->assertEqual($loadedAlias->get('path')->value, $alias['path'], format_string('Loaded the expected path with aid %aid.', array('%aid' => $aid)));
+      $this->assertEqual($loadedAlias->get('langcode')->value, $alias['langcode'], format_string('Loaded the expected langcode with aid %aid.', array('%aid' => $aid)));
     }
 
     //Update a few aliases
     foreach ($aliases as $alias) {
-      $fields = $aliasStorage->save($alias['source'], $alias['alias'] . '_updated', $alias['langcode'], $alias['pid']);
-
-      $this->assertEqual($alias['alias'], $fields['original']['alias']);
+      $loadedAlias = $this->container->get('entity.manager')
+        ->getStorage('alias')
+        ->load($alias['aid']);
+      $loadedAlias->alias = $alias['alias'] . '_updated';
+      $loadedAlias->save();
 
-      $result = $connection->query('SELECT pid FROM {url_alias} WHERE source = :source AND alias= :alias AND langcode = :langcode', array(':source' => $alias['source'], ':alias' => $alias['alias'] . '_updated', ':langcode' => $alias['langcode']));
-      $pid = $result->fetchField();
+      $result = $connection->query('SELECT aid FROM {alias_field_data} WHERE path = :path AND alias= :alias AND langcode = :langcode', array(':path' => $alias['path'], ':alias' => $alias['alias'] . '_updated', ':langcode' => $alias['langcode']));
+      $aid = $result->fetchField();
 
-      $this->assertEqual($pid, $alias['pid'], format_string('Updated entry for pid %pid.', array('%pid' => $pid)));
+      $this->assertEqual($aid, $alias['aid'], format_string('Updated entry for aid %aid.', array('%aid' => $aid)));
     }
 
     //Delete a few aliases
     foreach ($aliases as $alias) {
-      $pid = $alias['pid'];
-      $aliasStorage->delete(array('pid' => $pid));
+      $loadedAlias = $this->container->get('entity.manager')
+        ->getStorage('alias')
+        ->load($alias['aid']);
+      $loadedAlias->delete();
 
-      $result = $connection->query('SELECT * FROM {url_alias} WHERE pid = :pid', array(':pid' => $pid));
+      $result = $connection->query('SELECT * FROM {alias_field_data} WHERE aid = :aid', array(':aid' => $alias['aid']));
       $rows = $result->fetchAll();
 
-      $this->assertEqual(count($rows), 0, format_string('Deleted entry with pid %pid.', array('%pid' => $pid)));
+      $this->assertEqual(count($rows), 0, format_string('Deleted entry with aid %aid.', array('%aid' => $aid)));
     }
   }
 
   function testLookupPath() {
+    /** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */
+    $alias_storage = $this->container->get('entity.manager')->getStorage('alias');
+
     //Prepare database table.
     $connection = Database::getConnection();
-    $this->fixtures->createTables($connection);
+    $this->fixtures->createTables($connection, $this->container->get('entity.manager'));
 
     //Create AliasManager and Path object.
     $aliasManager = $this->container->get('path.alias_manager');
-    $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
 
     // Test the situation where the source is the same for multiple aliases.
     // Start with a language-neutral alias, which we will override.
-    $path = array(
-      'source' => "user/1",
+    $alias = array(
+      'path' => "user/1",
       'alias' => 'foo',
     );
 
-    $aliasStorage->save($path['source'], $path['alias']);
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), $path['alias'], 'Basic alias lookup works.');
-    $this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'Basic source lookup works.');
+    $alias_storage->create(
+        array(
+          'path' => $alias['path'],
+          'alias' => $alias['alias'],
+        )
+      )
+      ->save();
+    $this->assertEqual($aliasManager->getAliasByPath($alias['path']), $alias['alias'], 'Basic alias lookup works.');
+    $this->assertEqual($aliasManager->getPathByAlias($alias['alias']), $alias['path'], 'Basic source lookup works.');
 
     // Create a language specific alias for the default language (English).
-    $path = array(
-      'source' => "user/1",
+    $alias = array(
+      'path' => "user/1",
       'alias' => "users/Dries",
       'langcode' => 'en',
     );
-    $aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
+    $alias_storage->create(
+        array(
+          'path' => $alias['path'],
+          'alias' => $alias['alias'],
+          'langcode' => $alias['langcode'],
+        )
+      )
+      ->save();
     // Hook that clears cache is not executed with unit tests.
     \Drupal::service('path.alias_manager')->cacheClear();
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), $path['alias'], 'English alias overrides language-neutral alias.');
-    $this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'English source overrides language-neutral source.');
+    $this->assertEqual($aliasManager->getAliasByPath($alias['path']), $alias['alias'], 'English alias overrides language-neutral alias.');
+    $this->assertEqual($aliasManager->getPathByAlias($alias['alias']), $alias['path'], 'English source overrides language-neutral source.');
 
     // Create a language-neutral alias for the same path, again.
-    $path = array(
-      'source' => "user/1",
+    $alias = array(
+      'path' => "user/1",
       'alias' => 'bar',
     );
-    $aliasStorage->save($path['source'], $path['alias']);
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), "users/Dries", 'English alias still returned after entering a language-neutral alias.');
+    $alias_storage->create(
+        array(
+          'path' => $alias['path'],
+          'alias' => $alias['alias'],
+          'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+        )
+      )
+      ->save();
+    $this->assertEqual($aliasManager->getAliasByPath($alias['path']), "users/Dries", 'English alias still returned after entering a language-neutral alias.');
 
     // Create a language-specific (xx-lolspeak) alias for the same path.
-    $path = array(
-      'source' => "user/1",
+    $alias = array(
+      'path' => "user/1",
       'alias' => 'LOL',
-      'langcode' => 'xx-lolspeak',
+      'langcode' => 'af',
     );
-    $aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), "users/Dries", 'English alias still returned after entering a LOLspeak alias.');
+    $alias_storage->create(
+        array(
+          'path' => $alias['path'],
+          'alias' => $alias['alias'],
+          'langcode' => $alias['langcode'],
+        )
+      )
+      ->save();
+    $this->assertEqual($aliasManager->getAliasByPath($alias['path']), "users/Dries", 'English alias still returned after entering a LOLspeak alias.');
     // The LOLspeak alias should be returned if we really want LOLspeak.
-    $this->assertEqual($aliasManager->getAliasByPath($path['source'], 'xx-lolspeak'), 'LOL', 'LOLspeak alias returned if we specify xx-lolspeak to the alias manager.');
+    $this->assertEqual($aliasManager->getAliasByPath($alias['path'], 'af'), 'LOL', 'LOLspeak alias returned if we specify af to the alias manager.');
 
     // Create a new alias for this path in English, which should override the
     // previous alias for "user/1".
-    $path = array(
-      'source' => "user/1",
+    $alias = array(
+      'path' => "user/1",
       'alias' => 'users/my-new-path',
       'langcode' => 'en',
     );
-    $aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
+    $alias_storage->create(
+        array(
+          'path' => $alias['path'],
+          'alias' => $alias['alias'],
+          'langcode' => $alias['langcode'],
+        )
+      )
+      ->save();
     // Hook that clears cache is not executed with unit tests.
     $aliasManager->cacheClear();
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), $path['alias'], 'Recently created English alias returned.');
-    $this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'Recently created English source returned.');
+    $this->assertEqual($aliasManager->getAliasByPath($alias['path']), $alias['alias'], 'Recently created English alias returned.');
+    $this->assertEqual($aliasManager->getPathByAlias($alias['alias']), $alias['path'], 'Recently created English source returned.');
 
     // Remove the English aliases, which should cause a fallback to the most
     // recently created language-neutral alias, 'bar'.
-    $aliasStorage->delete(array('langcode' => 'en'));
+    $aids = $this->container->get('entity.query')->get('alias')
+      ->condition('langcode', 'en')
+      ->execute();
+    $alias_storage->delete($alias_storage->loadMultiple($aids));
     // Hook that clears cache is not executed with unit tests.
     $aliasManager->cacheClear();
-    $this->assertEqual($aliasManager->getAliasByPath($path['source']), 'bar', 'Path lookup falls back to recently created language-neutral alias.');
+    $this->assertEqual($aliasManager->getAliasByPath('user/1'), 'bar', 'Path lookup falls back to recently created language-neutral alias.');
 
     // Test the situation where the alias and language are the same, but
     // the source differs. The newer alias record should be returned.
-    $aliasStorage->save('user/2', 'bar');
+    $alias_storage->create(
+      array(
+        'path' => 'user/2',
+        'alias' => 'bar',
+        'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+      ))
+      ->save();
     // Hook that clears cache is not executed with unit tests.
     $aliasManager->cacheClear();
     $this->assertEqual($aliasManager->getPathByAlias('bar'), 'user/2', 'Newer alias record is returned when comparing two LanguageInterface::LANGCODE_NOT_SPECIFIED paths with the same alias.');
@@ -159,14 +238,13 @@ function testLookupPath() {
   function testWhitelist() {
     // Prepare database table.
     $connection = Database::getConnection();
-    $this->fixtures->createTables($connection);
+    $this->fixtures->createTables($connection, $this->container->get('entity.manager'));
 
     $memoryCounterBackend = new MemoryCounterBackend('default');
 
-    // Create AliasManager and Path object.
-    $aliasStorage = new AliasStorage($connection, $this->container->get('module_handler'));
-    $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage);
-    $aliasManager = new AliasManager($aliasStorage, $whitelist, $this->container->get('language_manager'), $memoryCounterBackend);
+    // Create AliasManager object.
+    $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('entity.manager'));
+    $aliasManager = new AliasManager($this->container->get('entity.manager'), $whitelist, $this->container->get('language_manager'), $memoryCounterBackend);
 
     // No alias for user and admin yet, so should be NULL.
     $this->assertNull($whitelist->get('user'));
@@ -177,21 +255,42 @@ function testWhitelist() {
     $this->assertNull($whitelist->get($this->randomMachineName()));
 
     // Add an alias for user/1, user should get whitelisted now.
-    $aliasStorage->save('user/1', $this->randomMachineName());
+    $this->container->get('entity.manager')
+      ->getStorage('alias')
+      ->create(
+        array(
+          'path' => 'user/1',
+          'alias' => $this->randomMachineName(),
+          'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+        )
+      )
+      ->save();
     $aliasManager->cacheClear();
     $this->assertTrue($whitelist->get('user'));
     $this->assertNull($whitelist->get('admin'));
     $this->assertNull($whitelist->get($this->randomMachineName()));
 
     // Add an alias for admin, both should get whitelisted now.
-    $aliasStorage->save('admin/something', $this->randomMachineName());
+    $this->container->get('entity.manager')
+    ->getStorage('alias')
+      ->create(
+        array(
+          'path' => 'admin/something',
+          'alias' => $this->randomMachineName(),
+          'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
+        )
+      )
+      ->save();
     $aliasManager->cacheClear();
     $this->assertTrue($whitelist->get('user'));
     $this->assertTrue($whitelist->get('admin'));
     $this->assertNull($whitelist->get($this->randomMachineName()));
 
     // Remove the user alias again, whitelist entry should be removed.
-    $aliasStorage->delete(array('source' => 'user/1'));
+    $aids = $this->container->get('entity.query')->get('alias')
+      ->condition('path', 'user/1')
+      ->execute();
+    $this->container->get('entity.manager')->getStorage('alias')->delete($this->container->get('entity.manager')->getStorage('alias')->loadMultiple($aids));
     $aliasManager->cacheClear();
     $this->assertNull($whitelist->get('user'));
     $this->assertTrue($whitelist->get('admin'));
@@ -204,7 +303,7 @@ function testWhitelist() {
 
     // Re-initialize the whitelist using the same cache backend, should load
     // from cache.
-    $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage);
+    $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('entity.manager'));
     $this->assertNull($whitelist->get('user'));
     $this->assertTrue($whitelist->get('admin'));
     $this->assertNull($whitelist->get($this->randomMachineName()));
diff --git a/core/modules/system/src/Tests/Path/PathUnitTestBase.php b/core/modules/system/src/Tests/Path/PathUnitTestBase.php
index 3d25b1b..2ead69b 100644
--- a/core/modules/system/src/Tests/Path/PathUnitTestBase.php
+++ b/core/modules/system/src/Tests/Path/PathUnitTestBase.php
@@ -29,7 +29,7 @@ protected function setUp() {
   }
 
   protected function tearDown() {
-    $this->fixtures->dropTables(Database::getConnection());
+    $this->fixtures->dropTables(Database::getConnection(), $this->container->get('entity.manager'));
 
     parent::tearDown();
   }
diff --git a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
index 777ffb1..60b2290 100644
--- a/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
+++ b/core/modules/system/src/Tests/Path/UrlAliasFixtures.php
@@ -3,6 +3,7 @@
 namespace Drupal\system\Tests\Path;
 
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Entity\EntityManagerInterface;
 
 /**
  * Utility methods to generate sample data, database configuration, etc.
@@ -15,7 +16,7 @@ class UrlAliasFixtures {
    * @param \Drupal\Core\Database\Connection $connection
    *   The connection to use to create the tables.
    */
-  public function createTables(Connection $connection) {
+  public function createTables(Connection $connection, EntityManagerInterface $entity_manager) {
     $tables = $this->tableDefinition();
     $schema = $connection->schema();
 
@@ -23,6 +24,9 @@ public function createTables(Connection $connection) {
       $schema->dropTable($name);
       $schema->createTable($name, $table);
     }
+
+    $entity_manager->onEntityTypeDelete($entity_manager->getDefinition('alias'));
+    $entity_manager->onEntityTypeCreate($entity_manager->getDefinition('alias'));
   }
 
   /**
@@ -31,13 +35,15 @@ public function createTables(Connection $connection) {
    * @param \Drupal\Core\Database\Connection $connection
    *   The connection to use to drop the tables.
    */
-  public function dropTables(Connection $connection) {
+  public function dropTables(Connection $connection, EntityManagerInterface $entity_manager) {
     $tables = $this->tableDefinition();
     $schema = $connection->schema();
 
     foreach ($tables as $name => $table) {
       $schema->dropTable($name);
     }
+
+    $entity_manager->onEntityTypeDelete($entity_manager->getDefinition('alias'));
   }
 
   /**
@@ -48,22 +54,22 @@ public function dropTables(Connection $connection) {
   public function sampleUrlAliases() {
     return array(
       array(
-        'source' => 'node/1',
+        'path' => 'node/1',
         'alias' => 'alias_for_node_1_en',
         'langcode' => 'en'
       ),
       array(
-        'source' => 'node/2',
+        'path' => 'node/2',
         'alias' => 'alias_for_node_2_en',
         'langcode' => 'en'
       ),
       array(
-        'source' => 'node/1',
+        'path' => 'node/1',
         'alias' => 'alias_for_node_1_fr',
         'langcode' => 'fr'
       ),
       array(
-        'source' => 'node/1',
+        'path' => 'node/1',
         'alias' => 'alias_for_node_1_und',
         'langcode' => 'und'
       )
@@ -83,7 +89,6 @@ public function tableDefinition() {
     module_load_install('system');
     $schema = system_schema();
 
-    $tables['url_alias'] = $schema['url_alias'];
     $tables['key_value'] = $schema['key_value'];
 
     return $tables;
diff --git a/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php b/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php
index c1d4b2a..0312acc 100644
--- a/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php
+++ b/core/modules/system/src/Tests/Plugin/Condition/RequestPathTest.php
@@ -54,8 +54,6 @@ class RequestPathTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->installSchema('system', array('sequences', 'url_alias'));
-
     $this->pluginManager = $this->container->get('plugin.manager.condition');
 
     // Set a mock alias manager in the container.
diff --git a/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php b/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php
index 2152474..316b055 100644
--- a/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php
+++ b/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php
@@ -74,8 +74,6 @@ public function testClear() {
    * Tests the generation of all system site information tokens.
    */
   public function testSystemSiteTokenReplacement() {
-    // The use of the url() function requires the url_alias table to exist.
-    $this->installSchema('system', 'url_alias');
     $url_options = array(
       'absolute' => TRUE,
       'language' => $this->interfaceLanguage,
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 4d3ba7e..037c840 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -934,43 +934,5 @@ function system_schema() {
     ),
   );
 
-  $schema['url_alias'] = array(
-    'description' => 'A list of URL aliases for Drupal paths; a user may visit either the source or destination path.',
-    'fields' => array(
-      'pid' => array(
-        'description' => 'A unique path alias identifier.',
-        'type' => 'serial',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-      ),
-      'source' => array(
-        'description' => 'The Drupal path this alias is for; e.g. node/12.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'alias' => array(
-        'description' => 'The alias for this path; e.g. title-of-the-story.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'langcode' => array(
-        'description' => "The language code this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.",
-        'type' => 'varchar',
-        'length' => 12,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-    ),
-    'primary key' => array('pid'),
-    'indexes' => array(
-      'alias_langcode_pid' => array('alias', 'langcode', 'pid'),
-      'source_langcode_pid' => array('source', 'langcode', 'pid'),
-    ),
-  );
-
   return $schema;
 }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 3f19f14..2b258e4 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1294,22 +1294,22 @@ function system_block_view_system_help_block_alter(array &$build, BlockPluginInt
 }
 
 /**
- * Implements hook_path_update().
+ * Implements hook_ENTITY_TYPE_update().
  */
-function system_path_update() {
+function system_alias_update() {
   \Drupal::service('path.alias_manager')->cacheClear();
 }
 
 /**
- * Implements hook_path_insert().
+ * Implements hook_ENTITY_TYPE_insert().
  */
-function system_path_insert() {
+function system_alias_insert() {
   \Drupal::service('path.alias_manager')->cacheClear();
 }
 
 /**
- * Implements hook_path_delete().
+ * Implements hook_ENTITY_TYPE_delete().
  */
-function system_path_delete($path) {
+function system_alias_delete() {
   \Drupal::service('path.alias_manager')->cacheClear();
 }
diff --git a/core/modules/system/tests/modules/path_test/path_test.module b/core/modules/system/tests/modules/path_test/path_test.module
index df03931..ea72f3c 100644
--- a/core/modules/system/tests/modules/path_test/path_test.module
+++ b/core/modules/system/tests/modules/path_test/path_test.module
@@ -13,10 +13,10 @@ function path_test_reset() {
 }
 
 /**
- * Implements hook_path_update().
+ * Implements hook_ENTITY_TYPE_update().
  */
-function path_test_path_update($path) {
+function path_test_alias_update($alias) {
   $results = \Drupal::state()->get('path_test.results') ?: array();
-  $results['hook_path_update'] = $path;
+  $results['hook_path_update'] = $alias;
   \Drupal::state()->set('path_test.results', $results);
 }
diff --git a/core/modules/text/src/Tests/TextSummaryTest.php b/core/modules/text/src/Tests/TextSummaryTest.php
index 27c660f..79a6646 100644
--- a/core/modules/text/src/Tests/TextSummaryTest.php
+++ b/core/modules/text/src/Tests/TextSummaryTest.php
@@ -21,7 +21,6 @@ class TextSummaryTest extends DrupalUnitTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->installSchema('system', 'url_alias');
     $this->installConfig(array('text'));
   }
 
diff --git a/core/modules/views/src/Tests/Handler/FieldUrlTest.php b/core/modules/views/src/Tests/Handler/FieldUrlTest.php
index 04ed05c..3c23c7e 100644
--- a/core/modules/views/src/Tests/Handler/FieldUrlTest.php
+++ b/core/modules/views/src/Tests/Handler/FieldUrlTest.php
@@ -28,7 +28,6 @@ class FieldUrlTest extends ViewUnitTestBase {
 
   protected function setUp() {
     parent::setUp();
-    $this->installSchema('system', 'url_alias');
   }
 
   function viewsData() {
diff --git a/core/modules/views/src/Tests/Plugin/DisplayPageTest.php b/core/modules/views/src/Tests/Plugin/DisplayPageTest.php
index 22896ce..8c6b8d5 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayPageTest.php
+++ b/core/modules/views/src/Tests/Plugin/DisplayPageTest.php
@@ -45,16 +45,6 @@ class DisplayPageTest extends ViewUnitTestBase {
   protected $routerDumper;
 
   /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    // Setup the needed tables in order to make the drupal router working.
-    $this->installSchema('system', array('url_alias'));
-  }
-
-  /**
    * Checks the behavior of the page for access denied/not found behaviors.
    */
   public function testPageResponses() {
diff --git a/core/modules/views/src/Tests/TokenReplaceTest.php b/core/modules/views/src/Tests/TokenReplaceTest.php
index bb97765..b47841d 100644
--- a/core/modules/views/src/Tests/TokenReplaceTest.php
+++ b/core/modules/views/src/Tests/TokenReplaceTest.php
@@ -25,11 +25,6 @@ class TokenReplaceTest extends ViewUnitTestBase {
    */
   public static $testViews = array('test_tokens');
 
-  protected function setUp() {
-    parent::setUp();
-    $this->installSchema('system', 'url_alias');
-  }
-
   /**
    * Tests core token replacements generated from a view.
    */
diff --git a/core/modules/views/src/Tests/ViewStorageTest.php b/core/modules/views/src/Tests/ViewStorageTest.php
index fc78a9e..58d6983 100644
--- a/core/modules/views/src/Tests/ViewStorageTest.php
+++ b/core/modules/views/src/Tests/ViewStorageTest.php
@@ -185,9 +185,6 @@ protected function displayTests() {
    * Tests the display related functions like getDisplaysList().
    */
   protected function displayMethodTests() {
-    // Enable the system module so l() can work using url_alias table.
-    $this->installSchema('system', 'url_alias');
-
     $config['display'] = array(
       'page_1' => array(
         'display_options' => array('path' => 'test'),
diff --git a/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php b/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php
index 86108a5..c54b751 100644
--- a/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Path/AliasManagerTest.php
@@ -51,6 +51,13 @@ class AliasManagerTest extends UnitTestCase {
   protected $languageManager;
 
   /**
+   * Entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $entityManager;
+
+  /**
    * Cache backend.
    *
    * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -78,11 +85,17 @@ protected function setUp() {
     parent::setUp();
 
     $this->aliasStorage = $this->getMock('Drupal\Core\Path\AliasStorageInterface');
+    $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
+    $this->entityManager->expects($this->any())
+      ->method('getStorage')
+      ->with('alias')
+      ->willReturn($this->aliasStorage);
+
     $this->aliasWhitelist = $this->getMock('Drupal\Core\Path\AliasWhitelistInterface');
     $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
     $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
 
-    $this->aliasManager = new AliasManager($this->aliasStorage, $this->aliasWhitelist, $this->languageManager, $this->cache);
+    $this->aliasManager = new AliasManager($this->entityManager, $this->aliasWhitelist, $this->languageManager, $this->cache);
 
   }
 
