diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 1f1a0eb..1f7e968 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -52,12 +52,21 @@ 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 entity_type_alter hook implementation to the end of the list.
     case 'entity_type_alter':
       $group = $implementations['content_translation'];
       unset($implementations['content_translation']);
       $implementations['content_translation'] = $group;
       break;
+    // Move our entity_prepare_form hook implementation to the beginning of the
+    // list, so that the entity in the form object is exchanged with its
+    // requested translation before any other hook implementations have had
+    // access on it.
+    case 'entity_prepare_form':
+      $group = $implementations['content_translation'];
+      unset($implementations['content_translation']);
+      $implementations = array_merge(array('content_translation' => $group), $implementations);
+      break;
   }
 }
 
@@ -568,3 +577,28 @@ function content_translation_page_attachments(&$page) {
     return;
   }
 }
+
+/**
+ * Implements hook_entity_prepare_form().
+ *
+ * Load an entity form in specific language as requested by URL query option.
+ */
+function content_translation_entity_prepare_form(EntityInterface $entity, $operation, FormStateInterface $form_state) {
+  if ($entity instanceof ContentEntityInterface) {
+
+    $content_translation_target = \Drupal::request()->get('content_translation_target');
+
+    if ($content_translation_target !== NULL) {
+      /** @var \Drupal\Core\Entity\EntityFormInterface $form_object*/
+      $form_object = $form_state->getFormObject();
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $entity_from_form_object*/
+      $entity_from_form_object = $form_object->getEntity();
+
+      if ($entity_from_form_object->language()->getId() != $content_translation_target && $entity_from_form_object->hasTranslation($content_translation_target)) {
+        $entity_from_form_object = $entity_from_form_object->getTranslation($content_translation_target);
+        $form_object->setEntity($entity_from_form_object);
+        $form_state->set('langcode', $content_translation_target);
+      }
+    }
+  }
+}
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
index 5a7429c..35fcb67 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
@@ -42,7 +42,8 @@ function testTranslationUI() {
     $this->doTestPublishedStatus();
     $this->doTestAuthoringInfo();
     $this->doTestTranslationEdit();
+    $this->doTestFormLanguageSwitch();
     $this->doTestTranslationChanged();
     $this->doTestTranslationDeletion();
   }
 
@@ -248,6 +249,20 @@ protected function doTestAuthoringInfo() {
   }
 
   /**
+   * Tests the form language switch functionality.
+   */
+  protected function doTestFormLanguageSwitch() {
+    $entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
+
+    $message = 'The form language can be switched to @langcode through a query string parameter';
+    foreach ($entity->getTranslationLanguages() as $langcode => $language) {
+      $url = $entity->urlInfo('edit-form', ['query' => ['content_translation_target' => $langcode]]);
+      $this->drupalGet($url);
+      $this->assertRaw($entity->getTranslation($langcode)->{$this->fieldName}->value, format_string($message, array('@langcode' => $langcode)));
+    }
+  }
+
+  /**
    * Tests translation deletion.
    */
   protected function doTestTranslationDeletion() {
