diff --git a/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php b/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php
index 59f2d0c..cad93c2 100644
--- a/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php
+++ b/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php
@@ -21,8 +21,27 @@
    * @param string $path
    *   The path to process, with a leading slash.
    * @param array $options
-   *   An array of options such as would be passed to the generator's
-   *   generateFromRoute() method.
+   *   (optional) An associative array of additional options, with the following
+   *   elements:
+   *   - 'query': An array of query key/value-pairs (without any URL-encoding)
+   *     to append to the URL.
+   *   - 'fragment': A fragment identifier (named anchor) to append to the URL.
+   *     Do not include the leading '#' character.
+   *   - 'absolute': Defaults to FALSE. Whether to force the output to be an
+   *     absolute link (beginning with http:). Useful for links that will be
+   *     displayed outside the site, such as in an RSS feed.
+   *   - 'language': An optional language object used to look up the alias
+   *     for the URL. If $options['language'] is omitted, it defaults to the
+   *     current language for the language type LanguageInterface::TYPE_URL.
+   *   - 'https': Whether this URL should point to a secure location. If not
+   *     defined, the current scheme is used, so the user stays on HTTP or HTTPS
+   *     respectively. TRUE enforces HTTPS and FALSE enforces HTTP.
+   *   - 'base_url': Only used internally by a path processor, for example, to
+   *     modify the base URL when a language dependent URL requires so.
+   *   - 'prefix': Only used internally, to modify the path when a language
+   *     dependent URL requires so.
+   *   - 'route': The route object for the given path. It will be set by
+   *     \Drupal\Core\Routing\UrlGenerator::generateFromRoute().
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The HttpRequest object representing the current request.
    * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php
index f3d1275..62ece64 100644
--- a/core/lib/Drupal/Core/Routing/UrlGenerator.php
+++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php
@@ -309,6 +309,9 @@ public function generateFromRoute($name, $parameters = array(), $options = array
     $name = $this->getRouteDebugMessage($name);
     $this->processRoute($name, $route, $parameters, $generated_url);
     $path = $this->getInternalPathFromRoute($name, $route, $parameters, $query_params);
+    // Outbound path processors might need the route object for the path, e.g.
+    // to get the path pattern.
+    $options['route'] = $route;
     $path = $this->processPath($path, $options, $generated_url);
 
     if (!empty($options['prefix'])) {
diff --git a/core/modules/content_translation/content_translation.install b/core/modules/content_translation/content_translation.install
index 0bfe414..0dfd587 100644
--- a/core/modules/content_translation/content_translation.install
+++ b/core/modules/content_translation/content_translation.install
@@ -29,3 +29,10 @@ function content_translation_enable() {
   $message = t('<a href=":settings_url">Enable translation</a> for <em>content types</em>, <em>taxonomy vocabularies</em>, <em>accounts</em>, or any other element you wish to translate.', $t_args);
   drupal_set_message($message, 'warning');
 }
+
+/**
+ * Rebuild the routes as the content translation routes have now new names.
+ */
+function content_translation_update_8001() {
+  \Drupal::service('router.builder')->rebuild();
+}
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index ff1b34d..b354e95 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -53,7 +53,7 @@ function content_translation_help($route_name, RouteMatchInterface $route_match)
  */
 function content_translation_module_implements_alter(&$implementations, $hook) {
   switch ($hook) {
-    // Move some of our hook implementations to the end of the list.
+    // Move our hook_entity_type_alter() implementation to the end of the list.
     case 'entity_type_alter':
       $group = $implementations['content_translation'];
       unset($implementations['content_translation']);
@@ -140,7 +140,11 @@ function content_translation_entity_type_alter(array &$entity_types) {
       if ($entity_type->hasLinkTemplate('canonical')) {
         // Provide default route names for the translation paths.
         if (!$entity_type->hasLinkTemplate('drupal:content-translation-overview')) {
-          $entity_type->setLinkTemplate('drupal:content-translation-overview', $entity_type->getLinkTemplate('canonical') . '/translations');
+          $translations_path = $entity_type->getLinkTemplate('canonical') . '/translations';
+          $entity_type->setLinkTemplate('drupal:content-translation-overview', $translations_path);
+          $entity_type->setLinkTemplate('drupal:content-translation-add', $translations_path . '/add/{source}/{target}');
+          $entity_type->setLinkTemplate('drupal:content-translation-edit', $translations_path . '/edit/{language}');
+          $entity_type->setLinkTemplate('drupal:content-translation-delete', $translations_path . '/delete/{language}');
         }
         // @todo Remove this as soon as menu access checks rely on the
         //   controller. See https://www.drupal.org/node/2155787.
diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php
index d7eb42a..1b8d77d 100644
--- a/core/modules/content_translation/src/ContentTranslationHandler.php
+++ b/core/modules/content_translation/src/ContentTranslationHandler.php
@@ -652,7 +652,7 @@ public function entityFormSourceChange($form, FormStateInterface $form_state) {
     $source = $form_state->getValue(array('source_langcode', 'source'));
 
     $entity_type_id = $entity->getEntityTypeId();
-    $form_state->setRedirect('content_translation.translation_add_' . $entity_type_id, array(
+    $form_state->setRedirect("entity.$entity_type_id.content_translation_add", array(
       $entity_type_id => $entity->id(),
       'source' => $source,
       'target' => $form_object->getFormLangcode($form_state),
@@ -689,7 +689,7 @@ function entityFormDeleteTranslation($form, FormStateInterface $form_state) {
       $form_state->setRedirectUrl($entity->urlInfo('delete-form'));
     }
     else {
-      $form_state->setRedirect('content_translation.translation_delete_' . $entity_type_id, [
+      $form_state->setRedirect("entity.$entity_type_id.content_translation_delete", [
         $entity_type_id => $entity->id(),
         'language' => $form_object->getFormLangcode($form_state),
       ]);
diff --git a/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php
index 9c6879a..8c19de1 100644
--- a/core/modules/content_translation/src/Controller/ContentTranslationController.php
+++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php
@@ -127,7 +127,7 @@ public function overview(RouteMatchInterface $route_match, $entity_type_id = NUL
         $langcode = $language->getId();
 
         $add_url = new Url(
-          'content_translation.translation_add_' . $entity_type_id,
+          "entity.$entity_type_id.content_translation_add",
           array(
             'source' => $original,
             'target' => $language->getId(),
@@ -138,7 +138,7 @@ public function overview(RouteMatchInterface $route_match, $entity_type_id = NUL
           )
         );
         $edit_url = new Url(
-          'content_translation.translation_edit_' . $entity_type_id,
+          "entity.$entity_type_id.content_translation_edit",
           array(
             'language' => $language->getId(),
             $entity_type_id => $entity->id(),
@@ -148,7 +148,7 @@ public function overview(RouteMatchInterface $route_match, $entity_type_id = NUL
           )
         );
         $delete_url = new Url(
-          'content_translation.translation_delete_' . $entity_type_id,
+          "entity.$entity_type_id.content_translation_delete",
           array(
             'language' => $language->getId(),
             $entity_type_id => $entity->id(),
diff --git a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
index a2b54a8..ebdf562 100644
--- a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
@@ -112,7 +112,7 @@ protected function alterRoutes(RouteCollection $collection) {
           '_admin_route' => $is_admin,
         )
       );
-      $collection->add("content_translation.translation_add_$entity_type_id", $route);
+      $collection->add("entity.$entity_type_id.content_translation_add", $route);
 
       $route = new Route(
         $path . '/edit/{language}',
@@ -137,7 +137,7 @@ protected function alterRoutes(RouteCollection $collection) {
           '_admin_route' => $is_admin,
         )
       );
-      $collection->add("content_translation.translation_edit_$entity_type_id", $route);
+      $collection->add("entity.$entity_type_id.content_translation_edit", $route);
 
       $route = new Route(
         $path . '/delete/{language}',
@@ -162,7 +162,7 @@ protected function alterRoutes(RouteCollection $collection) {
           '_admin_route' => $is_admin,
         )
       );
-      $collection->add("content_translation.translation_delete_$entity_type_id", $route);
+      $collection->add("entity.$entity_type_id.content_translation_delete", $route);
     }
   }
 
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
index 33d936a..1b79d13 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
@@ -107,7 +107,8 @@ protected function doTestBasicTranslation() {
     $language = ConfigurableLanguage::load($langcode);
     $values[$langcode] = $this->getNewEntityValues($langcode);
 
-    $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [
+    $entity_type_id = $entity->getEntityTypeId();
+    $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [
       $entity->getEntityTypeId() => $entity->id(),
       'source' => $default_langcode,
       'target' => $langcode
@@ -167,7 +168,8 @@ protected function doTestBasicTranslation() {
     $language = ConfigurableLanguage::load($langcode);
     $source_langcode = 'it';
     $edit = array('source_langcode[source]' => $source_langcode);
-    $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [
+    $entity_type_id =  $entity->getEntityTypeId();
+    $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [
       $entity->getEntityTypeId() => $entity->id(),
       'source' => $default_langcode,
       'target' => $langcode
@@ -180,7 +182,8 @@ protected function doTestBasicTranslation() {
     // Add another translation and mark the other ones as outdated.
     $values[$langcode] = $this->getNewEntityValues($langcode);
     $edit = $this->getEditValues($values, $langcode) + array('content_translation[retranslate]' => TRUE);
-    $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [
+    $entity_type_id = $entity->getEntityTypeId();
+    $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [
       $entity->getEntityTypeId() => $entity->id(),
       'source' => $source_langcode,
       'target' => $langcode
@@ -207,13 +210,15 @@ protected function doTestBasicTranslation() {
    */
   protected function doTestTranslationOverview() {
     $entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
-    $this->drupalGet($entity->urlInfo('drupal:content-translation-overview'));
+    $translate_url = $entity->urlInfo('drupal:content-translation-overview');
+    $this->drupalGet($translate_url);
+    $translate_url->setAbsolute(FALSE);
 
     foreach ($this->langcodes as $langcode) {
       if ($entity->hasTranslation($langcode)) {
         $language = new Language(array('id' => $langcode));
-        $view_path = $entity->url('canonical', array('language' => $language));
-        $elements = $this->xpath('//table//a[@href=:href]', array(':href' => $view_path));
+        $view_url = $entity->url('canonical', ['language' => $language]);
+        $elements = $this->xpath('//table//a[@href=:href]', [':href' => $view_url]);
         $this->assertEqual((string) $elements[0], $entity->getTranslation($langcode)->label(), format_string('Label correctly shown for %language translation.', array('%language' => $langcode)));
         $edit_path = $entity->url('edit-form', array('language' => $language));
         $elements = $this->xpath('//table//ul[@class="dropbutton"]/li/a[@href=:href]', array(':href' => $edit_path));
@@ -343,7 +348,7 @@ protected function doTestTranslationDeletion() {
 
     // Check that the translator cannot delete the original translation.
     $args = [$this->entityTypeId => $entity->id(), 'language' => 'en'];
-    $this->drupalGet(Url::fromRoute('content_translation.translation_delete_' . $this->entityTypeId, $args));
+    $this->drupalGet(Url::fromRoute("entity.$this->entityTypeId.content_translation_delete", $args));
     $this->assertResponse(403);
   }
 
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
index 9d8a052..63c1963 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
@@ -73,7 +73,7 @@ protected function setupEntity() {
 
     // Create a translation.
     $this->drupalLogin($this->translator);
-    $add_translation_url = Url::fromRoute('content_translation.translation_add_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $this->langcodes[2]]);
+    $add_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_add", [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $this->langcodes[2]]);
     $this->drupalPostForm($add_translation_url, array(), t('Save'));
     $this->rebuildContainer();
   }
@@ -175,7 +175,7 @@ protected function doTestWorkflows(UserInterface $user, $expected_status) {
     $this->assertResponse($expected_status['overview'], SafeMarkup::format('The @user_label has the expected translation overview access.', $args));
 
     // Check whether the user is allowed to create a translation.
-    $add_translation_url = Url::fromRoute('content_translation.translation_add_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $langcode], $options);
+    $add_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_add", [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $langcode], $options);
     if ($expected_status['add_translation'] == 200) {
       $this->clickLink('Add');
       $this->assertUrl($add_translation_url->toString(), [], 'The translation overview points to the translation form when creating translations.');
@@ -193,7 +193,7 @@ protected function doTestWorkflows(UserInterface $user, $expected_status) {
     // Check whether the user is allowed to edit a translation.
     $langcode = $this->langcodes[2];
     $options['language'] = $languages[$langcode];
-    $edit_translation_url = Url::fromRoute('content_translation.translation_edit_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options);
+    $edit_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_edit", [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options);
     if ($expected_status['edit_translation'] == 200) {
       $this->drupalGet($translations_url);
       $editor = $expected_status['edit'] == 200;
@@ -221,7 +221,7 @@ protected function doTestWorkflows(UserInterface $user, $expected_status) {
     // Check whether the user is allowed to delete a translation.
     $langcode = $this->langcodes[2];
     $options['language'] = $languages[$langcode];
-    $delete_translation_url = Url::fromRoute('content_translation.translation_delete_' . $this->entityTypeId, [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options);
+    $delete_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_delete", [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options);
     if ($expected_status['delete_translation'] == 200) {
       $this->drupalGet($translations_url);
       $editor = $expected_status['delete'] == 200;
diff --git a/core/modules/language/language.install b/core/modules/language/language.install
new file mode 100644
index 0000000..dcec16a
--- /dev/null
+++ b/core/modules/language/language.install
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Update functions for Language module.
+ */
+
+/**
+ * Rebuild the container as services changed.
+ */
+function language_update_8001() {
+  \Drupal::service('kernel')->invalidateContainer();
+}
diff --git a/core/modules/language/language.services.yml b/core/modules/language/language.services.yml
index fc9bba1..19d0f21 100644
--- a/core/modules/language/language.services.yml
+++ b/core/modules/language/language.services.yml
@@ -9,7 +9,7 @@ services:
       - [initLanguageManager]
   language.config_subscriber:
     class: Drupal\language\EventSubscriber\ConfigSubscriber
-    arguments: ['@language_manager', '@language.default', '@config.factory']
+    arguments: ['@language_manager', '@language.default', '@config.factory', '@language_negotiator']
     tags:
       - { name: event_subscriber }
   language.config_factory_override:
diff --git a/core/modules/language/src/EventSubscriber/ConfigSubscriber.php b/core/modules/language/src/EventSubscriber/ConfigSubscriber.php
index e1875ce..e43697b 100644
--- a/core/modules/language/src/EventSubscriber/ConfigSubscriber.php
+++ b/core/modules/language/src/EventSubscriber/ConfigSubscriber.php
@@ -14,6 +14,8 @@
 use Drupal\Core\Config\ConfigCrudEvent;
 use Drupal\Core\Config\ConfigEvents;
 use Drupal\language\ConfigurableLanguageManager;
+use Drupal\language\HttpKernel\PathProcessorLanguage;
+use Drupal\language\LanguageNegotiatorInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 /**
@@ -43,6 +45,20 @@ class ConfigSubscriber implements EventSubscriberInterface {
   protected $configFactory;
 
   /**
+   * The language negotiator.
+   *
+   * @var \Drupal\language\LanguageNegotiatorInterface
+   */
+  protected $languageNegotiator;
+
+  /**
+   * The language path processor.
+   *
+   * @var \Drupal\language\HttpKernel\PathProcessorLanguage
+   */
+  protected $pathProcessorLanguage;
+
+  /**
    * Constructs a new class object.
    *
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
@@ -51,11 +67,14 @@ class ConfigSubscriber implements EventSubscriberInterface {
    *   The default language.
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The configuration factory.
+   * @param \Drupal\language\LanguageNegotiatorInterface $language_negotiator
+   *   The language negotiator.
    */
-  public function __construct(LanguageManagerInterface $language_manager, LanguageDefault $language_default, ConfigFactoryInterface $config_factory) {
+  public function __construct(LanguageManagerInterface $language_manager, LanguageDefault $language_default, ConfigFactoryInterface $config_factory, LanguageNegotiatorInterface $language_negotiator) {
     $this->languageManager = $language_manager;
     $this->languageDefault = $language_default;
     $this->configFactory = $config_factory;
+    $this->languageNegotiator = $language_negotiator;
   }
 
   /**
@@ -102,6 +121,25 @@ public function onConfigSave(ConfigCrudEvent $event) {
       // Trigger a container rebuild on the next request by invalidating it.
       ConfigurableLanguageManager::rebuildServices();
     }
+    elseif($saved_config->getName() == 'language.types' && $event->isChanged('negotiation')) {
+      // If the negotiation configuration changed the language negotiator and
+      // the language path processor have to be reset so that they regenerate
+      // the method instances and also sort them accordingly to the new config.
+      $this->languageNegotiator->reset();
+      if (isset($this->pathProcessorLanguage)) {
+        $this->pathProcessorLanguage->reset();
+      }
+    }
+  }
+
+  /**
+   * Injects the language path processors on multilingual site configuration.
+   *
+   * @param \Drupal\language\HttpKernel\PathProcessorLanguage $path_processor_language
+   *   The language path processor.
+   */
+  public function setPathProcessorLanguage(PathProcessorLanguage $path_processor_language) {
+    $this->pathProcessorLanguage = $path_processor_language;
   }
 
   /**
diff --git a/core/modules/language/src/HttpKernel/PathProcessorLanguage.php b/core/modules/language/src/HttpKernel/PathProcessorLanguage.php
index caddfc0..aa58709 100644
--- a/core/modules/language/src/HttpKernel/PathProcessorLanguage.php
+++ b/core/modules/language/src/HttpKernel/PathProcessorLanguage.php
@@ -13,6 +13,7 @@
 use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\language\ConfigurableLanguageManagerInterface;
+use Drupal\language\EventSubscriber\ConfigSubscriber;
 use Drupal\language\LanguageNegotiatorInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Drupal\Core\Session\AccountInterface;
@@ -58,6 +59,14 @@ class PathProcessorLanguage implements InboundPathProcessorInterface, OutboundPa
   protected $multilingual;
 
   /**
+   * The language configuration event subscriber.
+   *
+   * @var \Drupal\language\EventSubscriber\ConfigSubscriber
+   */
+  protected $configSubscriber;
+
+
+  /**
    * Constructs a PathProcessorLanguage object.
    *
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config
@@ -68,12 +77,15 @@ class PathProcessorLanguage implements InboundPathProcessorInterface, OutboundPa
    *   The language negotiator.
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   The current active user.
+   * @param \Drupal\language\EventSubscriber\ConfigSubscriber $config_subscriber
+   *   The language configuration event subscriber.
    */
-  public function __construct(ConfigFactoryInterface $config, ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, AccountInterface $current_user) {
+  public function __construct(ConfigFactoryInterface $config, ConfigurableLanguageManagerInterface $language_manager, LanguageNegotiatorInterface $negotiator, AccountInterface $current_user, ConfigSubscriber $config_subscriber) {
     $this->config = $config;
     $this->languageManager = $language_manager;
     $this->negotiator = $negotiator;
     $this->negotiator->setCurrentUser($current_user);
+    $this->configSubscriber = $config_subscriber;
   }
 
   /**
@@ -152,4 +164,22 @@ protected function initProcessors($scope) {
     });
   }
 
+  /**
+   * Initializes the injected event subscriber with the language path processor.
+   *
+   * The language path processor service is registered only on multilingual
+   * site configuration, thus we inject it in the event subscriber only when
+   * it is initialized.
+   */
+  public function initConfigSubscriber() {
+    $this->configSubscriber->setPathProcessorLanguage($this);
+  }
+
+  /**
+   * Resets the collected processors instances.
+   */
+  public function reset() {
+    $this->processors = array();
+  }
+
 }
diff --git a/core/modules/language/src/LanguageServiceProvider.php b/core/modules/language/src/LanguageServiceProvider.php
index 2f1840c..c3f1cd1 100644
--- a/core/modules/language/src/LanguageServiceProvider.php
+++ b/core/modules/language/src/LanguageServiceProvider.php
@@ -39,7 +39,9 @@ public function register(ContainerBuilder $container) {
         ->addArgument(new Reference('config.factory'))
         ->addArgument(new Reference('language_manager'))
         ->addArgument(new Reference('language_negotiator'))
-        ->addArgument(new Reference('current_user'));
+        ->addArgument(new Reference('current_user'))
+        ->addArgument(new Reference('language.config_subscriber'))
+        ->addMethodCall('initConfigSubscriber');
     }
   }
 
diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentEntity.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentEntity.php
new file mode 100644
index 0000000..4ce022d
--- /dev/null
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationContentEntity.php
@@ -0,0 +1,294 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity.
+ */
+
+namespace Drupal\language\Plugin\LanguageNegotiation;
+
+use Drupal\Component\Utility\UrlHelper;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Render\BubbleableMetadata;
+use Drupal\Core\Url;
+use Drupal\language\LanguageNegotiationMethodBase;
+use Drupal\language\LanguageSwitcherInterface;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+
+/**
+ * Class for identifying the content translation language.
+ *
+ * @LanguageNegotiation(
+ *   id = Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity::METHOD_ID,
+ *   types = {Drupal\Core\Language\LanguageInterface::TYPE_CONTENT},
+ *   weight = -9,
+ *   name = @Translation("Content language"),
+ *   description = @Translation("Determines the content language from a request parameter."),
+ * )
+ */
+class LanguageNegotiationContentEntity extends LanguageNegotiationMethodBase implements OutboundPathProcessorInterface, LanguageSwitcherInterface, ContainerFactoryPluginInterface {
+
+  /**
+   * The language negotiation method ID.
+   */
+  const METHOD_ID = 'language-content-entity';
+
+  /**
+   * The query string parameter.
+   */
+  const QUERY_PARAMETER = 'language_content_entity';
+
+  /**
+   * A list of all the link paths of enabled content entities.
+   *
+   * @var array
+   */
+  protected $contentEntityPaths;
+
+  /**
+   * Static cache for the language negotiation order check.
+   *
+   * @see \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity::hasLowerLanguageNegotiationWeight()
+   *
+   * @var bool
+   */
+  protected $hasLowerLanguageNegotiationWeightResult;
+
+  /**
+   * Static cache of outbound route paths per request.
+   *
+   * @var \SplObjectStorage
+   */
+  protected $paths;
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * Constructs a new LanguageNegotiationContentEntity instance.
+   *
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(EntityManagerInterface $entity_manager) {
+    $this->entityManager = $entity_manager;
+    $this->paths = new \SplObjectStorage();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static($container->get('entity.manager'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLangcode(Request $request = NULL) {
+    $langcode = $request->get(static::QUERY_PARAMETER);
+
+    $language_enabled = array_key_exists($langcode, $this->languageManager->getLanguages());
+    return $language_enabled ? $langcode : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
+    // If appropriate, process outbound to add a query parameter to the url and
+    // remove the language option, so that url negotiator does not rewrite the
+    // url.
+
+    // First, check if processing conditions are met.
+    if (!($request && !empty($options['route']) && $this->hasLowerLanguageNegotiationWeight() && $this->meetsContentEntityRoutesCondition($options['route'], $request))) {
+      return $path;
+    }
+
+    if (isset($options['language']) || $langcode = $this->getLangcode($request)) {
+      // If the language option is set, unset it, so that the url language
+      // negotiator does not rewrite the url.
+      if (isset($options['language'])) {
+        $langcode = $options['language']->getId();
+        unset($options['language']);
+      }
+
+      if (isset($options['query']) && is_string($options['query'])) {
+        $query = [];
+        parse_str($options['query'], $query);
+        $options['query'] = $query;
+      }
+      else {
+        $options['query'] = [];
+      }
+
+      if (!isset($options['query'][static::QUERY_PARAMETER])) {
+        $query_addon = [static::QUERY_PARAMETER => $langcode];
+        $options['query'] += $query_addon;
+        // @todo Remove this once https://www.drupal.org/node/2507005 lands.
+        $path .= (strpos($path, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($query_addon);
+      }
+
+      if ($bubbleable_metadata) {
+        // Cached URLs that have been processed by this outbound path
+        // processor must be:
+        $bubbleable_metadata
+          // - varied by the content language query parameter.
+          ->addCacheContexts(['url.query_args:' . static::QUERY_PARAMETER]);
+      }
+    }
+
+    return $path;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLanguageSwitchLinks(Request $request, $type, Url $url) {
+    $links = [];
+    $query = [];
+    parse_str($request->getQueryString(), $query);
+
+    foreach ($this->languageManager->getNativeLanguages() as $language) {
+      $langcode = $language->getId();
+      $query[static::QUERY_PARAMETER] = $langcode;
+      $links[$langcode] = [
+        'url' => $url,
+        'title' => $language->getName(),
+        'attributes' => ['class' => ['language-link']],
+        'query' => $query,
+      ];
+    }
+
+    return $links;
+  }
+
+  /**
+   * Determines if content entity language negotiator has higher priority.
+   *
+   * The content entity language negotiator having higher priority than the url
+   * language negotiator, is a criteria in
+   * \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity::processOutbound().
+   *
+   * @return bool
+   *   TRUE if the the content entity language negotiator has higher priority
+   *   than the url language negotiator, FALSE otherwise.
+   */
+  protected function hasLowerLanguageNegotiationWeight() {
+    if (!isset($this->hasLowerLanguageNegotiationWeightResult)) {
+      // Only run if the LanguageNegotiationContentEntity outbound function is
+      // being executed before the outbound function of LanguageNegotiationUrl.
+      $content_method_weights = $this->config->get('language.types')->get('negotiation.language_content.enabled') ?: [];
+
+      // Check if the content language is configured to be dependent on the
+      // url negotiator directly or indirectly over the interface negotiator.
+      if (isset($content_method_weights[LanguageNegotiationUrl::METHOD_ID]) && ($content_method_weights[static::METHOD_ID] > $content_method_weights[LanguageNegotiationUrl::METHOD_ID])) {
+        $this->hasLowerLanguageNegotiationWeightResult = FALSE;
+      }
+      else {
+        $check_interface_method = FALSE;
+        if (isset($content_method_weights[LanguageNegotiationUI::METHOD_ID])) {
+          $interface_method_weights = $this->config->get('language.types')->get('negotiation.language_interface.enabled') ?: [];
+          $check_interface_method = isset($interface_method_weights[LanguageNegotiationUrl::METHOD_ID]);
+        }
+        if ($check_interface_method) {
+          $max_weight = $content_method_weights[LanguageNegotiationUI::METHOD_ID];
+          $max_weight = isset($content_method_weights[LanguageNegotiationUrl::METHOD_ID]) ? max($max_weight, $content_method_weights[LanguageNegotiationUrl::METHOD_ID]) : $max_weight;
+        }
+        else {
+          $max_weight = isset($content_method_weights[LanguageNegotiationUrl::METHOD_ID]) ? $content_method_weights[LanguageNegotiationUrl::METHOD_ID] : PHP_INT_MAX;
+        }
+
+        $this->hasLowerLanguageNegotiationWeightResult = $content_method_weights[static::METHOD_ID] < $max_weight;
+      }
+    }
+
+    return $this->hasLowerLanguageNegotiationWeightResult;
+  }
+
+  /**
+   * Determines if content entity route condition is met.
+   *
+   * Requirements: currently being on an content entity route and processing
+   * outbound url pointing to the same content entity.
+   *
+   * @param \Symfony\Component\Routing\Route $outbound_route
+   *   The route object for the current outbound url being processed.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The HttpRequest object representing the current request.
+   *
+   * @return bool
+   *   TRUE if the content entity route condition is met, FALSE otherwise.
+   */
+  protected function meetsContentEntityRoutesCondition(Route $outbound_route, Request $request) {
+    $outbound_path_pattern = $outbound_route->getPath();
+    $storage = isset($this->paths[$request]) ? $this->paths[$request] : [];
+    if (!isset($storage[$outbound_path_pattern])) {
+      $storage[$outbound_path_pattern] = FALSE;
+
+      // Check if the outbound route points to the current entity.
+      if ($content_entity_type_id_for_current_route = $this->getContentEntityTypeIdForCurrentRequest($request)) {
+        if (!empty($this->getContentEntityPaths()[$outbound_path_pattern]) && $content_entity_type_id_for_current_route == $this->getContentEntityPaths()[$outbound_path_pattern]) {
+          $storage[$outbound_path_pattern] = TRUE;
+        }
+      }
+
+      $this->paths[$request] = $storage;
+    }
+
+    return $storage[$outbound_path_pattern];
+  }
+
+  /**
+   * Returns the content entity type ID from the current request for the route.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The HttpRequest object representing the current request.
+   *
+   * @return string
+   *   The entity type ID for the route from the request.
+   */
+  protected function getContentEntityTypeIdForCurrentRequest(Request $request) {
+    $content_entity_type_id_for_current_route = '';
+
+    if ($current_route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) {
+      $current_route_path = $current_route->getPath();
+      $content_entity_type_id_for_current_route = isset($this->getContentEntityPaths()[$current_route_path]) ? $this->getContentEntityPaths()[$current_route_path] : '';
+    }
+
+    return $content_entity_type_id_for_current_route;
+  }
+
+  /**
+   * Returns the paths for the link templates of all content entities.
+   *
+   * @return array
+   *   An array of all content entity type IDs, keyed by the corresponding link
+   *   template paths.
+   */
+  protected function getContentEntityPaths() {
+    if (!isset($this->contentEntityPaths)) {
+      $this->contentEntityPaths = [];
+      $entity_types = $this->entityManager->getDefinitions();
+      foreach ($entity_types as $entity_type_id => $entity_type) {
+        if ($entity_type->isSubclassOf(ContentEntityInterface::class)) {
+          $entity_paths = array_fill_keys($entity_type->getLinkTemplates(), $entity_type_id);
+          $this->contentEntityPaths = array_merge($this->contentEntityPaths, $entity_paths);
+        }
+      }
+    }
+
+    return $this->contentEntityPaths;
+  }
+
+}
diff --git a/core/modules/language/src/Tests/EntityUrlLanguageTest.php b/core/modules/language/src/Tests/EntityUrlLanguageTest.php
index 915f7f6..f172b38 100644
--- a/core/modules/language/src/Tests/EntityUrlLanguageTest.php
+++ b/core/modules/language/src/Tests/EntityUrlLanguageTest.php
@@ -7,22 +7,34 @@
 
 namespace Drupal\language\Tests;
 
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\KernelTestBase;
+use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity;
+use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
 
 /**
  * Tests the language of entity URLs.
  * @group language
  */
-class EntityUrlLanguageTest extends KernelTestBase {
+class EntityUrlLanguageTest extends LanguageTestBase {
 
   /**
    * Modules to enable.
    *
    * @var array
    */
-  public static $modules = ['language', 'entity_test', 'user', 'system'];
+  public static $modules = ['entity_test', 'user'];
+
+  /**
+   * The entity being used for testing.
+   *
+   * @var \Drupal\Core\Entity\ContentEntityInterface
+   */
+  protected $entity;
 
   protected function setUp() {
     parent::setUp();
@@ -37,33 +49,93 @@ protected function setUp() {
     ConfigurableLanguage::create(['id' => 'es'])->save();
     ConfigurableLanguage::create(['id' => 'fr'])->save();
 
-    $this->config('language.types')->setData([
-      'configurable' => ['language_interface'],
-      'negotiation' => ['language_interface' => ['enabled' => ['language-url' => 0]]],
-    ])->save();
-    $this->config('language.negotiation')->setData([
-      'url' => [
-        'source' => 'path_prefix',
-        'prefixes' => ['en' => 'en', 'es' => 'es', 'fr' => 'fr']
-      ],
-    ])->save();
+    $config = $this->config('language.negotiation');
+    $config->set('url.prefixes', ['en' => 'en', 'es' => 'es', 'fr' => 'fr'])
+      ->save();
     $this->kernel->rebuildContainer();
-    $this->container = $this->kernel->getContainer();
-    \Drupal::setContainer($this->container);
+
+    $this->createTranslatableEntity();
   }
 
   /**
    * Ensures that entity URLs in a language have the right language prefix.
    */
   public function testEntityUrlLanguage() {
-    $entity = EntityTest::create();
-    $entity->addTranslation('es', ['name' => 'name spanish']);
-    $entity->addTranslation('fr', ['name' => 'name french']);
-    $entity->save();
-
-    $this->assertTrue(strpos($entity->urlInfo()->toString(), '/en/entity_test/' . $entity->id()) !== FALSE);
-    $this->assertTrue(strpos($entity->getTranslation('es')->urlInfo()->toString(), '/es/entity_test/' . $entity->id()) !== FALSE);
-    $this->assertTrue(strpos($entity->getTranslation('fr')->urlInfo()->toString(), '/fr/entity_test/' . $entity->id()) !== FALSE);
+    $this->assertTrue(strpos($this->entity->urlInfo()->toString(), '/en/entity_test/' . $this->entity->id()) !== FALSE);
+    $this->assertTrue(strpos($this->entity->getTranslation('es')->urlInfo()->toString(), '/es/entity_test/' . $this->entity->id()) !== FALSE);
+    $this->assertTrue(strpos($this->entity->getTranslation('fr')->urlInfo()->toString(), '/fr/entity_test/' . $this->entity->id()) !== FALSE);
+  }
+
+  /**
+   * Ensures correct entity URLs with the method language-content-entity enabled.
+   *
+   * Test case with the method language-content-entity enabled and configured
+   * with higher and also with lower priority than the method language-url.
+   */
+  public function testEntityUrlLanguageWithLanguageContentEnabled() {
+    // Define the method language-content-entity with a higher priority than
+    // language-url.
+    $config = $this->config('language.types');
+    $config->set('configurable', [LanguageInterface::TYPE_INTERFACE, LanguageInterface::TYPE_CONTENT]);
+    $config->set('negotiation.language_content.enabled', [
+      LanguageNegotiationContentEntity::METHOD_ID => 0,
+      LanguageNegotiationUrl::METHOD_ID => 1
+    ]);
+    $config->save();
+
+    // Without being on an content entity route the default entity URL tests
+    // should still pass.
+    $this->testEntityUrlLanguage();
+
+    // Now switching to an entity route, so that the URL links are generated
+    // while being on an entity route.
+    $this->setCurrentRequestForRoute('/entity_test/{entity_test}', 'entity.entity_test.canonical');
+
+    // The method language-content-entity should run before language-url and
+    // append query parameter for the content language and prevent language-url
+    // from overwriting the url.
+    $this->assertTrue(strpos($this->entity->urlInfo('canonical')->toString(), '/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=en') !== FALSE);
+    $this->assertTrue(strpos($this->entity->getTranslation('es')->urlInfo('canonical')->toString(), '/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=es') !== FALSE);
+    $this->assertTrue(strpos($this->entity->getTranslation('fr')->urlInfo('canonical')->toString(), '/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=fr') !== FALSE);
+
+    // Define the method language-url with a higher priority than
+    // language-content-entity. This configuration should match the default one,
+    // where the language-content-entity is turned off.
+    $config->set('negotiation.language_content.enabled', [
+      LanguageNegotiationUrl::METHOD_ID => 0,
+      LanguageNegotiationContentEntity::METHOD_ID => 1
+    ]);
+    $config->save();
+
+    // The default entity URL tests should pass again with the current
+    // configuration.
+    $this->testEntityUrlLanguage();
+  }
+
+  /**
+   * Creates a translated entity.
+   */
+  protected function createTranslatableEntity() {
+    $this->entity = EntityTest::create();
+    $this->entity->addTranslation('es', ['name' => 'name spanish']);
+    $this->entity->addTranslation('fr', ['name' => 'name french']);
+    $this->entity->save();
+  }
+
+  /**
+   * Sets the current request to a specific path with the corresponding route.
+   *
+   * @param string $path
+   *   The path for which the current request should be created.
+   * @param string $route_name
+   *   The route name for which the route object for the request should be
+   *   created.
+   */
+  protected function setCurrentRequestForRoute($path, $route_name) {
+    $request = Request::create($path);
+    $request->attributes->set(RouteObjectInterface::ROUTE_NAME, $route_name);
+    $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route($path));
+    $this->container->get('request_stack')->push($request);
   }
 
 }
diff --git a/core/modules/language/src/Tests/LanguageNegotiationContentEntityTest.php b/core/modules/language/src/Tests/LanguageNegotiationContentEntityTest.php
new file mode 100644
index 0000000..5373096
--- /dev/null
+++ b/core/modules/language/src/Tests/LanguageNegotiationContentEntityTest.php
@@ -0,0 +1,182 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Tests\LanguageNegotiationLanguageContentEntityTest.
+ */
+
+namespace Drupal\language\Tests;
+
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity;
+use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
+use Drupal\simpletest\WebTestBase;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+
+/**
+ * Tests language negotiation with the language negotiator content entity.
+ *
+ * @group language
+ */
+class LanguageNegotiationContentEntityTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('language', 'language_test', 'entity_test', 'system');
+
+  /**
+   * The entity being used for testing.
+   *
+   * @var \Drupal\Core\Entity\ContentEntityInterface
+   */
+  protected $entity;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    ConfigurableLanguage::create(['id' => 'es'])->save();
+    ConfigurableLanguage::create(['id' => 'fr'])->save();
+
+    // In order to reflect the changes for a multilingual site in the container
+    // we have to rebuild it.
+    $this->rebuildContainer();
+
+    $this->createTranslatableEntity();
+
+    $user = $this->drupalCreateUser(array('view test entity'));
+    $this->drupalLogin($user);
+  }
+
+  /**
+   * Tests default with content language remaining same as interface language.
+   */
+  public function testDefaultConfiguration() {
+    $translation = $this->entity;
+    $this->drupalGet($translation->urlInfo());
+    $last = $this->container->get('state')->get('language_test.language_negotiation_last');
+    $last_content_language = $last[LanguageInterface::TYPE_CONTENT];
+    $last_interface_language = $last[LanguageInterface::TYPE_INTERFACE];
+    $this->assertTrue(($last_interface_language == $last_content_language) && ($last_content_language == $translation->language()->getId()), new FormattableMarkup('Interface language %interface_language and Content language %content_language are the same as the translation language %translation_language of the entity.', ['%interface_language' => $last_interface_language, '%content_language' => $last_content_language, '%translation_language' => $translation->language()->getId()]));
+
+    $translation = $this->entity->getTranslation('es');
+    $this->drupalGet($translation->urlInfo());
+    $last = $this->container->get('state')->get('language_test.language_negotiation_last');
+    $last_content_language = $last[LanguageInterface::TYPE_CONTENT];
+    $last_interface_language = $last[LanguageInterface::TYPE_INTERFACE];
+    $this->assertTrue(($last_interface_language == $last_content_language) && ($last_content_language == $translation->language()->getId()), new FormattableMarkup('Interface language %interface_language and Content language %content_language are the same as the translation language %translation_language of the entity.', ['%interface_language' => $last_interface_language, '%content_language' => $last_content_language, '%translation_language' => $translation->language()->getId()]));
+
+    $translation = $this->entity->getTranslation('fr');
+    $this->drupalGet($translation->urlInfo());
+    $last = $this->container->get('state')->get('language_test.language_negotiation_last');
+    $last_content_language = $last[LanguageInterface::TYPE_CONTENT];
+    $last_interface_language = $last[LanguageInterface::TYPE_INTERFACE];
+    $this->assertTrue(($last_interface_language == $last_content_language) && ($last_content_language == $translation->language()->getId()), new FormattableMarkup('Interface language %interface_language and Content language %content_language are the same as the translation language %translation_language of the entity.', ['%interface_language' => $last_interface_language, '%content_language' => $last_content_language, '%translation_language' => $translation->language()->getId()]));
+  }
+
+  /**
+   * Tests enabling the language negotiator language_content_entity.
+   */
+  public function testEnabledLanguageContentNegotiator() {
+    // Define the method language-url with a higher priority than
+    // language-content-entity. This configuration should match the default one,
+    // where the language-content-entity is turned off.
+    $config = $this->config('language.types');
+    $config->set('configurable', [LanguageInterface::TYPE_INTERFACE, LanguageInterface::TYPE_CONTENT]);
+    $config->set('negotiation.language_content.enabled', [
+      LanguageNegotiationUrl::METHOD_ID => 0,
+      LanguageNegotiationContentEntity::METHOD_ID => 1
+    ]);
+    $config->save();
+
+    // In order to reflect the changes for a multilingual site in the container
+    // we have to rebuild it.
+    $this->rebuildContainer();
+
+    // The tests for the default configuration should still pass.
+    $this->testDefaultConfiguration();
+
+    // Define the method language-content-entity with a higher priority than
+    // language-url.
+    $config->set('negotiation.language_content.enabled', [
+      LanguageNegotiationContentEntity::METHOD_ID => 0,
+      LanguageNegotiationUrl::METHOD_ID => 1
+    ]);
+    $config->save();
+
+    // In order to reflect the changes for a multilingual site in the container
+    // we have to rebuild it.
+    $this->rebuildContainer();
+
+    // The method language-content-entity should run before language-url and
+    // append query parameter for the content language and prevent language-url
+    // from overwriting the URL.
+    $default_site_langcode = $this->config('system.site')->get('default_langcode');
+
+    // Now switching to an entity route, so that the URL links are generated
+    // while being on an entity route.
+    $this->setCurrentRequestForRoute('/entity_test/{entity_test}', 'entity.entity_test.canonical');
+
+    $translation = $this->entity;
+    $this->drupalGet($translation->urlInfo());
+    $last = $this->container->get('state')->get('language_test.language_negotiation_last');
+    $last_content_language = $last[LanguageInterface::TYPE_CONTENT];
+    $last_interface_language = $last[LanguageInterface::TYPE_INTERFACE];
+    $this->assertTrue(($last_interface_language == $default_site_langcode) && ($last_interface_language == $last_content_language) && ($last_content_language == $translation->language()->getId()), 'Interface language and Content language are the same as the default translation language of the entity.');
+    $this->assertTrue($last_interface_language == $default_site_langcode, 'Interface language did not change from the default site language.');
+    $this->assertTrue($last_content_language == $translation->language()->getId(), 'Content language matches the current entity translation language.');
+
+    $translation = $this->entity->getTranslation('es');
+    $this->drupalGet($translation->urlInfo());
+    $last = $this->container->get('state')->get('language_test.language_negotiation_last');
+    $last_content_language = $last[LanguageInterface::TYPE_CONTENT];
+    $last_interface_language = $last[LanguageInterface::TYPE_INTERFACE];
+    $this->assertTrue($last_interface_language == $default_site_langcode, 'Interface language did not change from the default site language.');
+    $this->assertTrue($last_content_language == $translation->language()->getId(), 'Content language matches the current entity translation language.');
+
+    $translation = $this->entity->getTranslation('fr');
+    $this->drupalGet($translation->urlInfo());
+    $last = $this->container->get('state')->get('language_test.language_negotiation_last');
+    $last_content_language = $last[LanguageInterface::TYPE_CONTENT];
+    $last_interface_language = $last[LanguageInterface::TYPE_INTERFACE];
+    $this->assertTrue($last_interface_language == $default_site_langcode, 'Interface language did not change from the default site language.');
+    $this->assertTrue($last_content_language == $translation->language()->getId(), 'Content language matches the current entity translation language.');
+  }
+
+  /**
+   * Creates a translated entity.
+   */
+  protected function createTranslatableEntity() {
+    $this->entity = EntityTest::create();
+    $this->entity->addTranslation('es', ['name' => 'name spanish']);
+    $this->entity->addTranslation('fr', ['name' => 'name french']);
+    $this->entity->save();
+  }
+
+  /**
+   * Sets the current request to a specific path with the corresponding route.
+   *
+   * @param string $path
+   *   The path for which the current request should be created.
+   * @param string $route_name
+   *   The route name for which the route object for the request should be
+   *   created.
+   */
+  protected function setCurrentRequestForRoute($path, $route_name) {
+    $request = Request::create($path);
+    $request->attributes->set(RouteObjectInterface::ROUTE_NAME, $route_name);
+    $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route($path));
+    $this->container->get('request_stack')->push($request);
+  }
+
+}
diff --git a/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php
index 4645d68..16ba13e 100644
--- a/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php
@@ -221,8 +221,13 @@ function testUILanguageNegotiation() {
 
     // Unknown language prefix should return 404.
     $definitions = \Drupal::languageManager()->getNegotiator()->getNegotiationMethods();
+    // Enable only methods, which are either not limited to a specific language
+    // type or are supporting the interface language type.
+    $language_interface_method_definitions = array_filter($definitions, function ($method_definition) {
+      return !isset($method_definition['types']) || (isset($method_definition['types']) && in_array(LanguageInterface::TYPE_INTERFACE, $method_definition['types']));
+    });
     $this->config('language.types')
-      ->set('negotiation.' . LanguageInterface::TYPE_INTERFACE . '.enabled', array_flip(array_keys($definitions)))
+      ->set('negotiation.' . LanguageInterface::TYPE_INTERFACE . '.enabled', array_flip(array_keys($language_interface_method_definitions)))
       ->save();
     $this->drupalGet("$langcode_unknown/admin/config", array(), $http_header_browser_fallback);
     $this->assertResponse(404, "Unknown language path prefix should return 404");
diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php
index b42eb76..0bb81c0 100644
--- a/core/modules/node/src/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/src/Tests/NodeTranslationUITest.php
@@ -94,7 +94,8 @@ public function testPublishedStatusNoFields() {
     $language = ConfigurableLanguage::load($langcode);
     $values[$langcode] = array('title' => array(array('value' => $this->randomMachineName())));
 
-    $add_url = Url::fromRoute('content_translation.translation_add_' . $entity->getEntityTypeId(), [
+    $entity_type_id = $entity->getEntityTypeId();
+    $add_url = Url::fromRoute("entity.$entity_type_id.content_translation_add", [
       $entity->getEntityTypeId() => $entity->id(),
       'source' => $default_langcode,
       'target' => $langcode
diff --git a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php b/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
index 956849c..fa14999 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
@@ -30,8 +30,7 @@ protected function setDatabaseDumpFiles() {
    * Tests that the content and configuration were properly updated.
    */
   public function testUpdatedSite() {
-    // @todo there are no updates to run.
-    //$this->runUpdates();
+    $this->runUpdates();
 
     $spanish = \Drupal::languageManager()->getLanguage('es');
 
diff --git a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
index d01a1f6..da61f5f 100644
--- a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
+++ b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
@@ -150,11 +150,16 @@ function testProcessInbound() {
     $current_user = $this->getMockBuilder('Drupal\Core\Session\AccountInterface')
       ->getMock();
 
+    // Create a config event subscriber stub.
+    $config_subscriber = $this->getMockBuilder('Drupal\language\EventSubscriber\ConfigSubscriber')
+      ->disableOriginalConstructor()
+      ->getMock();
+
     // Create the processors.
     $alias_processor = new PathProcessorAlias($alias_manager);
     $decode_processor = new PathProcessorDecode();
     $front_processor = new PathProcessorFront($config_factory_stub);
-    $language_processor = new PathProcessorLanguage($config_factory_stub, $this->languageManager, $negotiator, $current_user);
+    $language_processor = new PathProcessorLanguage($config_factory_stub, $this->languageManager, $negotiator, $current_user, $config_subscriber);
 
     // First, test the processor manager with the processors in the incorrect
     // order. The alias processor will run before the language processor, meaning
