diff --git a/core/modules/link/link.install b/core/modules/link/link.install
new file mode 100644
index 000000000..0153aed10
--- /dev/null
+++ b/core/modules/link/link.install
@@ -0,0 +1,69 @@
+<?php
+
+use \Drupal\link\Plugin\Field\FieldWidget\LinkWidget;
+
+/**
+ * @file
+ * Install, update and uninstall functions for the link module.
+ */
+
+/**
+ * Validate all entities with link fields for invalidly saved links.
+ */
+function link_update_8001(&$sandbox = NULL) {
+  if (!isset($sandbox['current_entity'])) {
+    // Get all entity types that has a link field, and cycle all entities for
+    // validating against the latest link widget validation.
+    $entity_manager = \Drupal::entityTypeManager();
+    $entity_types = $entity_manager->getDefinitions();
+    $sandbox['max'] = 0;
+    foreach ($entity_types as $entity_type) {
+      if ($entity_type->isSubclassOf('\Drupal\Core\Entity\FieldableEntityInterface')) {
+        // Throw all entities in the queue.
+        $sandbox['current_entity'] = 0;
+        $sandbox['current_entity_index'] = 0;
+        $query = \Drupal::entityQuery($entity_type->id());
+        $sandbox['entities'][] = [
+          'entity' => $entity_type->id(),
+          'ids' => $query->execute(),
+        ];
+      }
+    }
+  }
+  $page_size = 20;
+  $entities_to_process = array_slice($sandbox['entities'][$sandbox['current_entity']]['ids'], $sandbox['current_entity_index'], $page_size);
+  $entity_type_name = $sandbox['entities'][$sandbox['current_entity']]['entity'];
+  $entities_loaded = entity_load_multiple($entity_type_name, $entities_to_process);
+  /** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
+  foreach ($entities_loaded as $entity) {
+    // See if it has a link field.
+    $fields = $entity->getFields(FALSE);
+    /** @var \Drupal\Core\Field\FieldItemListInterface $field */
+    foreach ($fields as $field) {
+      $item_definition = $field->getItemDefinition();
+      if ($item_definition->getDataType() == 'field_item:link') {
+        // Try to run the validation.
+        /** @var \Drupal\Core\Field\FieldItemListInterface $a */
+        foreach ($entity->get($field->getName())->getValue() as $value) {
+          if (!LinkWidget::urlWillProcessAsUserEntered(LinkWidget::getUriAsDisplayableString($value['uri']))) {
+            drupal_set_message(t('The @type entity with the id @id has a field that will be displayed differently than the user input suggests. If this is unintended, please verify your settings for this entity.', [
+              '@type' => $entity_type_name,
+              '@id' => $entity->id(),
+            ]), 'error');
+          }
+        }
+      }
+    }
+
+  }
+  //print_r($sandbox);
+  $sandbox['current_entity_index'] += $page_size;
+  if ($sandbox['current_entity_index'] > count($sandbox['entities'][$sandbox['current_entity']])) {
+    $sandbox['current_entity_index'] = 0;
+    $sandbox['current_entity']++;
+  }
+  $sandbox['#finished'] = $sandbox['current_entity'] / count($sandbox['entities']);
+  if ($sandbox['#finished'] >= 1) {
+    return t('Links validated. Please see output for results.');
+  }
+}
\ No newline at end of file
diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
index 278e8010a..1923192f6 100644
--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -50,7 +50,7 @@ public static function defaultSettings() {
    *
    * @see static::getUserEnteredStringAsUri()
    */
-  protected static function getUriAsDisplayableString($uri) {
+  public static function getUriAsDisplayableString($uri) {
     $scheme = parse_url($uri, PHP_URL_SCHEME);
 
     // By default, the displayable string is the URI.
@@ -133,6 +133,76 @@ protected static function getUserEnteredStringAsUri($string) {
     return $uri;
   }
 
+  /**
+   * Checks if a user entered link will end up being processed as entered.
+   *
+   * One example is a user entering /en on a multilingual page and expecting the
+   * link to resolve to the English front page, while it in practice will
+   * resolve to the front page in the current language.
+   *
+   * @param string $user_link
+   *   A user entered string, like the one entered in the widget.
+   *
+   * @return bool
+   *   Whether the URL will resolve as the user entered it or not.
+   */
+  public static function urlWillProcessAsUserEntered($user_link) {
+    $language_manager = \Drupal::languageManager();
+    // Create a URL object from that.
+    $user_url = \Drupal::pathValidator()->getUrlIfValid($user_link);
+    if ($user_url) {
+      // If the user entered the special case "<front>" we must allow this
+      // to not correspond to what Drupal thinks the URL is.
+      $base_path = \Drupal::service('request_stack')
+        ->getCurrentRequest()
+        ->getBasePath();
+      if (strpos($user_link, '<front>') === 0) {
+        // Need to append the '/' for comparison.
+        $user_link = str_replace('<front>', $base_path . '/', $user_link);
+      }
+      $user_link = $base_path . $user_link;
+      // Compare the generated link with what Drupal thinks this is. We want
+      // to do this without language prefixes, if applicable. We also strip
+      // the fragments and query parameters, because those can confuse path
+      // resolving, and make for false errors.
+      $user_url->setOptions(['language' => $language_manager->getDefaultLanguage()]);
+      // Also, we want to allow the user to enter an aliased or non-aliased
+      // path.
+      $display_url = $user_url->toString();
+      // On update.php this will end up being prefixed with update.php.
+      if (strpos($display_url, '/update.php') === 0) {
+        $display_url = str_replace('/update.php', '', $display_url);
+      }
+      $non_aliased_path_search = $display_url;
+      // Remove the base path to search for the alias. And for displaying to
+      // the user, if it comes to that.
+      if ($base_path) {
+        $display_url = substr_replace($display_url, '', 0, strlen($base_path));
+        $non_aliased_path_search = substr_replace($non_aliased_path_search, '', 0, strlen($base_path));
+      }
+      // Prepend back the base path after resolving the alias.
+      $non_aliased_path = $base_path . \Drupal::service('path.alias_manager')
+          ->getPathByAlias($non_aliased_path_search);
+      // Some times, for example in our tests, the front page can be set to
+      // something else than "/". In that case, our validator will tell the
+      // user that the link is not valid because the link resolves to
+      // something else than "/". So, make sure "/" is fine, if it resolves
+      // to the front page.
+      if (parse_url($user_link, PHP_URL_PATH) == $base_path . '/' || parse_url($user_link, PHP_URL_PATH) == $base_path . '') {
+        // Compare to front page config.
+        $front = \Drupal::config('system.site')->get('page.front');
+        if ($user_url->toString() == $base_path . $front) {
+          // Just change the comparison user link. This will be allowed.
+          $user_link = $user_url->toString();
+        }
+      }
+      if (strpos($user_link, $user_url->toString()) !== 0 && strpos($user_link, $non_aliased_path) !== 0) {
+        return FALSE;
+      }
+    }
+    return TRUE;
+  }
+
   /**
    * Form element validation handler for the 'uri' element.
    *
@@ -146,9 +216,23 @@ public static function validateUriElement($element, FormStateInterface $form_sta
     // URI , ensure the raw value begins with '/', '?' or '#'.
     // @todo '<front>' is valid input for BC reasons, may be removed by
     //   https://www.drupal.org/node/2421941
-    if (parse_url($uri, PHP_URL_SCHEME) === 'internal' && !in_array($element['#value'][0], ['/', '?', '#'], TRUE) && substr($element['#value'], 0, 7) !== '<front>') {
-      $form_state->setError($element, t('Manually entered paths should start with one of the following characters: / ? #'));
-      return;
+    if (parse_url($uri, PHP_URL_SCHEME) === 'internal') {
+      if (!in_array($element['#value'][0], ['/', '?', '#'], TRUE) && substr($element['#value'], 0, 7) !== '<front>') {
+        $form_state->setError($element, t('Manually entered paths should start with one of the following characters: / ? #'));
+        return;
+      }
+      $user_link = $element['#value'];
+      // If the URL is internal, we want to check that the link will resolve in
+      // a way the user expects.
+      // Find the user input and validate that no URL negotiator will end up
+      // changing this URL to something else. For example if a user is
+      // entering a URL with a language prefix.
+      if (!static::urlWillProcessAsUserEntered($user_link)) {
+        $display_url = \Drupal::pathValidator()->getUrlIfValid($user_link)->toString();
+        $form_state->setError($element, t('The link you entered is not valid. One reason can be that you entered a link with a language prefix. Did you for example mean to link to @url?', [
+          '@url' => $display_url,
+        ]));
+      }
     }
   }
 
@@ -214,14 +298,21 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
 
     // If the field is configured to allow only internal links, add a useful
     // element prefix and description.
+    $language_manager = \Drupal::languageManager();
     if (!$this->supportsExternalLinks()) {
       $element['uri']['#field_prefix'] = rtrim(Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString(), '/');
       $element['uri']['#description'] = $this->t('This must be an internal path such as %add-node. You can also start typing the title of a piece of content to select it. Enter %front to link to the front page. Enter %nolink to display link text only.', ['%add-node' => '/node/add', '%front' => '<front>', '%nolink' => '<nolink>']);
+      // If the site is multilingual, warn the user that language prefixes will
+      // be stripped off, and the link will not be saved.
+      if ($language_manager->isMultilingual()) {
+        $element['uri']['#description'] .= ' ';
+        $element['uri']['#description'] .= $this->t('Be aware that it is not possible to save internal links with language prefixes.');
+      }
     }
     // If the field is configured to allow both internal and external links,
     // show a useful description.
     elseif ($this->supportsExternalLinks() && $this->supportsInternalLinks()) {
-      $element['uri']['#description'] = $this->t('Start typing the title of a piece of content to select it. You can also enter an internal path such as %add-node or an external URL such as %url. Enter %front to link to the front page. Enter %nolink to display link text only.', ['%front' => '<front>', '%add-node' => '/node/add', '%url' => 'http://example.com', '%nolink' => '<nolink>']);
+      $element['uri']['#description'] = $this->t('Start typing the title of a piece of content to select it. You can also enter an internal path such as %add-node or an external URL such as %url. Enter %front to link to the front page. Enter %nolink to display link text only. Be aware that it is not possible to save internal links with language prefixes.', ['%front' => '<front>', '%add-node' => '/node/add', '%url' => 'http://example.com', '%nolink' => '<nolink>']);
     }
     // If the field is configured to allow only external links, show a useful
     // description.
diff --git a/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentTranslationUITest.php b/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentTranslationUITest.php
index badeb9cc0..f2c7f38ee 100644
--- a/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentTranslationUITest.php
+++ b/core/modules/menu_link_content/tests/src/Functional/MenuLinkContentTranslationUITest.php
@@ -103,6 +103,24 @@ public function testTranslationLinkTheme() {
     $this->assertRaw('core/themes/seven/css/base/elements.css', 'Translation uses admin theme as well.');
   }
 
+  /**
+   * Tests that linking to another language prefixed path triggers an error.
+   */
+  function testMenuLinkLanguagePrefixValidation() {
+    $this->drupalLogin($this->administrator);
+
+    // Add a menu link in the tools menu.
+    $edit = array(
+      'title[0][value]' => 'Invalid link with language prefix',
+      // Link to an Italian admin page. Should not be allowed.
+      'link[0][uri]' => '/it/admin/structure/menu',
+    );
+    $this->drupalPostForm('admin/structure/menu/manage/tools/add', $edit, t('Save'));
+    $this->assertRaw(t('The link you entered is not valid. One reason can be that you entered a link with a language prefix. Did you for example mean to link to @url?', [
+      '@url' => '/admin/structure/menu',
+    ]));
+  }
+
   /**
    * {@inheritdoc}
    */
