diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
index ee03361..449c5e3 100644
--- a/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
+++ b/core/modules/path/src/Plugin/Field/FieldType/PathFieldItemList.php
@@ -34,4 +34,28 @@ public function delete() {
     \Drupal::service('path.alias_storage')->delete($conditions);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getValue($include_computed = FALSE) {
+    // Automatically create the first item for computed fields.
+    // @todo: Move this to the base class in https://www.drupal.org/node/2848418.
+    if (!isset($this->list[0]) && $this->definition->isComputed()) {
+      $this->list[0] = $this->createItem(0);
+    }
+    return parent::getValue($include_computed);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmpty() {
+    // Automatically create the first item for computed fields.
+    // @todo: Move this to the base class in https://www.drupal.org/node/2848418.
+    if (!isset($this->list[0]) && $this->definition->isComputed()) {
+      $this->list[0] = $this->createItem(0);
+    }
+    return parent::isEmpty();
+  }
+
 }
diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
index 239588f..78bbdda 100644
--- a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
+++ b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php
@@ -23,6 +23,13 @@
 class PathItem extends FieldItemBase {
 
   /**
+   * Whether the alias has been loaded from the alias storage service yet.
+   *
+   * @var bool
+   */
+  protected $isLoaded = FALSE;
+
+  /**
    * {@inheritdoc}
    */
   public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
@@ -30,12 +37,22 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
       ->setLabel(t('Path alias'));
     $properties['pid'] = DataDefinition::create('integer')
       ->setLabel(t('Path id'));
+    $properties['langcode'] = DataDefinition::create('string')
+      ->setLabel(t('Language Code'));
     return $properties;
   }
 
   /**
    * {@inheritdoc}
    */
+  public function __get($name) {
+    $this->ensureLoaded();
+    return parent::__get($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public static function schema(FieldStorageDefinitionInterface $field_definition) {
     return array();
   }
@@ -43,6 +60,22 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
   /**
    * {@inheritdoc}
    */
+  public function getValue() {
+    $this->ensureLoaded();
+    return parent::getValue();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmpty() {
+    $this->ensureLoaded();
+    return parent::isEmpty();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function preSave() {
     $this->alias = trim($this->alias);
   }
@@ -60,6 +93,15 @@ public function postSave($update) {
       }
     }
     else {
+      // The alias might have been auto-loaded for a different langcode before
+      // a translation was added. If the langcode property does not match the
+      // field langcode, then unset the path alias ID to store it as a new
+      // alias.
+      // @todo Revisit this in https://www.drupal.org/node/2511968
+      if ($this->pid && $this->langcode != $this->getLangcode()) {
+        $this->pid = NULL;
+      }
+
       // Delete old alias if user erased it.
       if ($this->pid && !$this->alias) {
         \Drupal::service('path.alias_storage')->delete(array('pid' => $this->pid));
@@ -88,4 +130,21 @@ public static function mainPropertyName() {
     return 'alias';
   }
 
+  /**
+   * Ensures the alias properties are loaded if available.
+   */
+  protected function ensureLoaded() {
+    $entity = $this->getEntity();
+    if (!$this->isLoaded && !$entity->isNew()) {
+      $alias = \Drupal::service('path.alias_storage')->load([
+        'source' => '/' . $entity->toUrl()->getInternalPath(),
+        'langcode' => $this->getLangcode(),
+      ]);
+      if ($alias) {
+        $this->setValue($alias);
+      }
+      $this->isLoaded = TRUE;
+    }
+  }
+
 }
diff --git a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
index 366db88..e2bbf2a 100644
--- a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
+++ b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php
@@ -5,7 +5,6 @@
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\WidgetBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Language\LanguageInterface;
 use Symfony\Component\Validator\ConstraintViolationInterface;
 
 /**
@@ -26,23 +25,6 @@ class PathWidget extends WidgetBase {
    */
   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
     $entity = $items->getEntity();
-    $path = array();
-    if (!$entity->isNew()) {
-      $conditions = array('source' => '/' . $entity->urlInfo()->getInternalPath());
-      if ($items->getLangcode() != LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-        $conditions['langcode'] = $items->getLangcode();
-      }
-      $path = \Drupal::service('path.alias_storage')->load($conditions);
-      if ($path === FALSE) {
-        $path = array();
-      }
-    }
-    $path += array(
-      'pid' => NULL,
-      'source' => !$entity->isNew() ? '/' . $entity->urlInfo()->getInternalPath() : NULL,
-      'alias' => '',
-      'langcode' => $items->getLangcode(),
-    );
 
     $element += array(
       '#element_validate' => array(array(get_class($this), 'validateFormElement')),
@@ -50,22 +32,28 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $element['alias'] = array(
       '#type' => 'textfield',
       '#title' => $element['#title'],
-      '#default_value' => $path['alias'],
+      '#default_value' => $items->alias,
       '#required' => $element['#required'],
       '#maxlength' => 255,
       '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "/about" when writing an about page.'),
     );
+    $pid = $items->pid;
+    $content_translation = $form_state->get('content_translation');
+    if (isset($content_translation['target'])) {
+      // If creating a new translation do not use the existing pid.
+      $pid = NULL;
+    }
     $element['pid'] = array(
       '#type' => 'value',
-      '#value' => $path['pid'],
+      '#value' => $pid,
     );
     $element['source'] = array(
       '#type' => 'value',
-      '#value' => $path['source'],
+      '#value' => !$entity->isNew() ? '/' . $entity->toUrl()->getInternalPath() : NULL,
     );
     $element['langcode'] = array(
       '#type' => 'value',
-      '#value' => $path['langcode'],
+      '#value' => $items->getLangcode(),
     );
     return $element;
   }
diff --git a/core/modules/path/tests/src/Kernel/PathItemTest.php b/core/modules/path/tests/src/Kernel/PathItemTest.php
new file mode 100644
index 0000000..461c596
--- /dev/null
+++ b/core/modules/path/tests/src/Kernel/PathItemTest.php
@@ -0,0 +1,109 @@
+<?php
+
+namespace Drupal\Tests\path\Kernel;
+
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
+
+/**
+ * Tests loading and storing data using PathItem.
+ *
+ * @group path
+ */
+class PathItemTest extends KernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('path', 'node', 'user', 'system');
+
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('node');
+    $this->installEntitySchema('user');
+
+    $this->installSchema('node', ['node_access']);
+
+    \Drupal::service('router.builder')->rebuild();
+
+    $node_type = NodeType::create(['type' => 'foo']);
+    $node_type->save();
+
+  }
+
+  /**
+   * Tests for no canonical link templates.
+   */
+  public function testPathItem() {
+
+    /** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */
+    $alias_storage = \Drupal::service('path.alias_storage');
+
+    $node_storage = \Drupal::entityTypeManager()->getStorage('node');
+
+    $node = Node::create([
+      'title' => 'Testing create()',
+      'type' => 'foo',
+      'path' => ['alias' => '/foo']
+    ]);
+    $this->assertFalse($node->get('path')->isEmpty());
+    $this->assertEquals('/foo', $node->get('path')->alias);
+
+    $node->save();
+    $this->assertFalse($node->get('path')->isEmpty());
+    $this->assertEquals('/foo', $node->get('path')->alias);
+
+    $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
+    $this->assertEquals('/foo', $stored_alias);
+
+    $node_storage->resetCache();
+    $loaded_node = $node_storage->load($node->id());
+    $this->assertFalse($loaded_node->get('path')->isEmpty());
+    $this->assertEquals('/foo', $loaded_node->get('path')->alias);
+
+    $node_storage->resetCache();
+    $loaded_node = $node_storage->load($node->id());
+    $values = $loaded_node->get('path')->getValue();
+    $this->assertEquals('/foo', $values[0]['alias']);
+
+    $loaded_node->get('path')->alias = '/bar';
+    $this->assertFalse($loaded_node->get('path')->isEmpty());
+    $this->assertEquals('/bar', $loaded_node->get('path')->alias);
+
+    $loaded_node->save();
+    $this->assertFalse($loaded_node->get('path')->isEmpty());
+    $this->assertEquals('/bar', $loaded_node->get('path')->alias);
+
+    $node_storage->resetCache();
+    $loaded_node = $node_storage->load($node->id());
+    $this->assertFalse($loaded_node->get('path')->isEmpty());
+    $this->assertEquals('/bar', $loaded_node->get('path')->alias);
+
+    $loaded_node->get('path')->alias = '/bar';
+    $this->assertFalse($loaded_node->get('path')->isEmpty());
+    $this->assertEquals('/bar', $loaded_node->get('path')->alias);
+
+    $loaded_node->save();
+    $this->assertFalse($loaded_node->get('path')->isEmpty());
+    $this->assertEquals('/bar', $loaded_node->get('path')->alias);
+
+    $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
+    $this->assertEquals('/bar', $stored_alias);
+
+    $old_alias = $alias_storage->lookupPathSource('/foo', $node->language()->getId());
+    $this->assertFalse($old_alias);
+
+    $loaded_node->get('path')->alias = '';
+    $this->assertEquals('', $loaded_node->get('path')->alias);
+
+    $loaded_node->save();
+
+    $stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
+    $this->assertFalse($stored_alias);
+  }
+
+}
