diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php
index 788786a93c08eb0d3afc83a3f0796329a395333e..28529eb0b29023d3503df3c81675af9af0bf042d 100644
--- a/core/modules/content_translation/src/ContentTranslationHandler.php
+++ b/core/modules/content_translation/src/ContentTranslationHandler.php
@@ -11,12 +11,14 @@
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\Entity\EntityHandlerInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Render\Element;
+use Drupal\Core\Session\AccountInterface;
 use Drupal\user\Entity\User;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -56,6 +58,21 @@ class ContentTranslationHandler implements ContentTranslationHandlerInterface, E
    */
   protected $manager;
 
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * The array of installed field storage definitions for the entity type, keyed
+   * by field name.
+   *
+   * @var \Drupal\Core\Field\FieldStorageDefinitionInterface[]
+   */
+  protected $fieldStorageDefinitions;
+
   /**
    * Initializes an instance of the content translation controller.
    *
@@ -65,12 +82,18 @@ class ContentTranslationHandler implements ContentTranslationHandlerInterface, E
    *   The language manager.
    * @param \Drupal\content_translation\ContentTranslationManagerInterface $manager
    *   The content translation manager service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
    */
-  public function __construct(EntityTypeInterface $entity_type, LanguageManagerInterface $language_manager, ContentTranslationManagerInterface $manager) {
+  public function __construct(EntityTypeInterface $entity_type, LanguageManagerInterface $language_manager, ContentTranslationManagerInterface $manager, EntityManagerInterface $entity_manager, AccountInterface $current_user) {
     $this->entityTypeId = $entity_type->id();
     $this->entityType = $entity_type;
     $this->languageManager = $language_manager;
     $this->manager = $manager;
+    $this->currentUser = $current_user;
+    $this->fieldStorageDefinitions = $entity_manager->getLastInstalledFieldStorageDefinitions($this->entityTypeId);
   }
 
   /**
@@ -80,7 +103,9 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
     return new static(
       $entity_type,
       $container->get('language_manager'),
-      $container->get('content_translation.manager')
+      $container->get('content_translation.manager'),
+      $container->get('entity.manager'),
+      $container->get('current_user')
     );
   }
 
@@ -111,6 +136,7 @@ public function getFieldDefinitions() {
         ->setSetting('target_type', 'user')
         ->setSetting('handler', 'default')
         ->setRevisionable(TRUE)
+        ->setDefaultValueCallback(get_class($this) . '::getDefaultOwnerId')
         ->setTranslatable(TRUE);
     }
 
@@ -149,7 +175,11 @@ public function getFieldDefinitions() {
    *   TRUE if metadata is natively supported, FALSE otherwise.
    */
   protected function hasAuthor() {
-    return is_subclass_of($this->entityType->getClass(), '\Drupal\user\EntityOwnerInterface');
+    // Check for field named uid, but only in case the entity implements the
+    // EntityOwnerInterface. This helps to exclude cases, where the uid is
+    // defined as field name, but is not meant to be an owner field e.g. the
+    // User entity.
+    return $this->entityType->isSubclassOf('\Drupal\user\EntityOwnerInterface') && $this->checkFieldStorageDefinitionTranslatability('uid');
   }
 
   /**
@@ -159,7 +189,7 @@ protected function hasAuthor() {
    *   TRUE if metadata is natively supported, FALSE otherwise.
    */
   protected function hasPublishedStatus() {
-    return array_key_exists('status', \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($this->entityType->id()));
+    return $this->checkFieldStorageDefinitionTranslatability('status');
   }
 
   /**
@@ -169,7 +199,7 @@ protected function hasPublishedStatus() {
    *   TRUE if metadata is natively supported, FALSE otherwise.
    */
   protected function hasChangedTime() {
-    return is_subclass_of($this->entityType->getClass(), '\Drupal\Core\Entity\EntityChangedInterface');
+    return $this->entityType->isSubclassOf('Drupal\Core\Entity\EntityChangedInterface') && $this->checkFieldStorageDefinitionTranslatability('changed');
   }
 
   /**
@@ -179,7 +209,23 @@ protected function hasChangedTime() {
    *   TRUE if metadata is natively supported, FALSE otherwise.
    */
   protected function hasCreatedTime() {
-    return array_key_exists('created', \Drupal::entityManager()->getLastInstalledFieldStorageDefinitions($this->entityType->id()));
+    return $this->checkFieldStorageDefinitionTranslatability('created');
+  }
+
+  /**
+   * Checks the field storage definition for translatability support.
+   *
+   * Checks whether the given field is defined in the field storage definitions
+   * and if its definition specifies it as translatable.
+   *
+   * @param string $field_name
+   *   The name of the field.
+   *
+   * @return bool
+   *   TRUE if translatable field storage definition exists, FALSE otherwise.
+   */
+  protected function checkFieldStorageDefinitionTranslatability($field_name) {
+    return array_key_exists($field_name, $this->fieldStorageDefinitions) && $this->fieldStorageDefinitions[$field_name]->isTranslatable();
   }
 
   /**
@@ -203,11 +249,10 @@ public function getTranslationAccess(EntityInterface $entity, $op) {
     $translate_permission = TRUE;
     // If no permission granularity is defined this entity type does not need an
     // explicit translate permission.
-    $current_user = \Drupal::currentUser();
-    if (!$current_user->hasPermission('translate any entity') && $permission_granularity = $entity_type->getPermissionGranularity()) {
-      $translate_permission = $current_user->hasPermission($permission_granularity == 'bundle' ? "translate {$entity->bundle()} {$entity->getEntityTypeId()}" : "translate {$entity->getEntityTypeId()}");
+    if (!$this->currentUser->hasPermission('translate any entity') && $permission_granularity = $entity_type->getPermissionGranularity()) {
+      $translate_permission = $this->currentUser->hasPermission($permission_granularity == 'bundle' ? "translate {$entity->bundle()} {$entity->getEntityTypeId()}" : "translate {$entity->getEntityTypeId()}");
     }
-    return AccessResult::allowedIf($translate_permission && $current_user->hasPermission("$op content translations"))->cachePerPermissions();
+    return AccessResult::allowedIf($translate_permission && $this->currentUser->hasPermission("$op content translations"))->cachePerPermissions();
   }
 
   /**
@@ -392,7 +437,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En
       // Default to the anonymous user.
       $uid = 0;
       if ($new_translation) {
-        $uid = \Drupal::currentUser()->getAccount()->id();
+        $uid = $this->currentUser->id();
       }
       elseif (($account = $metadata->getAuthor()) && $account->id()) {
         $uid = $account->id();
@@ -633,4 +678,13 @@ protected function entityFormTitle(EntityInterface $entity) {
     return $entity->label();
   }
 
+  /**
+   * Default value callback for the owner base field definition.
+   *
+   * @return int
+   *   The user ID.
+   */
+  public static function getDefaultOwnerId() {
+    return \Drupal::currentUser()->id();
+  }
 }
diff --git a/core/modules/content_translation/src/ContentTranslationMetadataWrapper.php b/core/modules/content_translation/src/ContentTranslationMetadataWrapper.php
index 4b4d43ea94e3b0b6c057aa6cacf5e362a85d2171..7dd958d2893a3f866fcd72a13ea88977941c9e6c 100644
--- a/core/modules/content_translation/src/ContentTranslationMetadataWrapper.php
+++ b/core/modules/content_translation/src/ContentTranslationMetadataWrapper.php
@@ -83,12 +83,8 @@ public function getAuthor() {
    * {@inheritdoc}
    */
   public function setAuthor(UserInterface $account) {
-    if ($this->translation->hasField('content_translation_uid')) {
-      $this->translation->set('content_translation_uid', $account->id());
-    }
-    else {
-      $this->translation->setOwner($account);
-    }
+    $field_name = $this->translation->hasField('content_translation_uid') ? 'content_translation_uid' : 'uid';
+    $this->setFieldOnlyIfTranslatable($field_name, $account->id());
     return $this;
   }
 
@@ -105,7 +101,7 @@ public function isPublished() {
    */
   public function setPublished($published) {
     $field_name = $this->translation->hasField('content_translation_status') ? 'content_translation_status' : 'status';
-    $this->translation->set($field_name, $published);
+    $this->setFieldOnlyIfTranslatable($field_name, $published);
     return $this;
   }
 
@@ -122,7 +118,7 @@ public function getCreatedTime() {
    */
   public function setCreatedTime($timestamp) {
     $field_name = $this->translation->hasField('content_translation_created') ? 'content_translation_created' : 'created';
-    $this->translation->set($field_name, $timestamp);
+    $this->setFieldOnlyIfTranslatable($field_name, $timestamp);
     return $this;
   }
 
@@ -138,8 +134,21 @@ public function getChangedTime() {
    */
   public function setChangedTime($timestamp) {
     $field_name = $this->translation->hasField('content_translation_changed') ? 'content_translation_changed' : 'changed';
-    $this->translation->set($field_name, $timestamp);
+    $this->setFieldOnlyIfTranslatable($field_name, $timestamp);
     return $this;
   }
 
+  /**
+   * Updates a field value, only if the field is translatable.
+   *
+   * @param string $field_name
+   *   The name of the field.
+   * @param mixed $value
+   *   The field value to be set.
+   */
+  protected function setFieldOnlyIfTranslatable($field_name, $value) {
+    if ($this->translation->getFieldDefinition($field_name)->isTranslatable()) {
+      $this->translation->set($field_name, $value);
+    }
+  }
 }
diff --git a/core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php b/core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php
index b0ced475d91b31d7b633ab55b815c7e2821e7f39..1089b99e98696808285802aa407ad5a06b793e70 100644
--- a/core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php
+++ b/core/modules/content_translation/src/ContentTranslationMetadataWrapperInterface.php
@@ -64,6 +64,8 @@ public function getAuthor();
   /**
    * Sets the translation author.
    *
+   * The metadata field will be updated, only if it's translatable.
+   *
    * @param \Drupal\user\UserInterface $account
    *   The translation author user entity.
    *
@@ -82,6 +84,8 @@ public function isPublished();
   /**
    * Sets the translation published status.
    *
+   * The metadata field will be updated, only if it's translatable.
+   *
    * @param bool $published
    *   TRUE if the translation is published, FALSE otherwise.
    *
@@ -100,6 +104,8 @@ public function getCreatedTime();
   /**
    * Sets the translation creation timestamp.
    *
+   * The metadata field will be updated, only if it's translatable.
+   *
    * @param int $timestamp
    *   The UNIX timestamp of when the translation was created.
    *
@@ -118,6 +124,8 @@ public function getChangedTime();
   /**
    * Sets the translation modification timestamp.
    *
+   * The metadata field will be updated, only if it's translatable.
+   *
    * @param int $timestamp
    *   The UNIX timestamp of when the translation was last modified.
    *
diff --git a/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php
index bae6a940e19b835225d7dd392b750ac25e58f29c..1d13630e30c1ba0aefaceed36121cccc4f33298c 100644
--- a/core/modules/content_translation/src/Controller/ContentTranslationController.php
+++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php
@@ -57,7 +57,16 @@ public static function create(ContainerInterface $container) {
   public function prepareTranslation(ContentEntityInterface $entity, LanguageInterface $source, LanguageInterface $target) {
     /* @var \Drupal\Core\Entity\ContentEntityInterface $source_translation */
     $source_translation = $entity->getTranslation($source->getId());
-    $entity->addTranslation($target->getId(), $source_translation->toArray());
+    $target_translation = $entity->addTranslation($target->getId(), $source_translation->toArray());
+
+    /** @var \Drupal\user\UserInterface $user */
+    $user = $this->entityManager()->getStorage('user')->load($this->currentUser()->id());
+    $metadata = $this->manager->getTranslationMetadata($target_translation);
+
+    // Update the translation author to current user, as well the translation
+    // creation time.
+    $metadata->setAuthor($user);
+    $metadata->setCreatedTime(REQUEST_TIME);
   }
 
   /**
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationMetadataFieldsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationMetadataFieldsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..437be686da64bd087afde564c9d2f688351615fe
--- /dev/null
+++ b/core/modules/content_translation/src/Tests/ContentTranslationMetadataFieldsTest.php
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\content_translation\Tests\ContentTranslationMetadataFieldsTest.
+ */
+
+namespace Drupal\content_translation\Tests;
+
+/**
+ * Tests the Content Translation metadata fields handling.
+ *
+ * @group content_translation
+ */
+class ContentTranslationMetadataFieldsTest extends ContentTranslationTestBase {
+
+  /**
+   * The entity type being tested.
+   *
+   * @var string
+   */
+  protected $entityTypeId = 'node';
+
+  /**
+   * The bundle being tested.
+   *
+   * @var string
+   */
+  protected $bundle = 'article';
+
+  /**
+   * Modules to install.
+   *
+   * @var array
+   */
+  public static $modules = array('language', 'content_translation', 'node');
+
+  /**
+   * The profile to install as a basis for testing.
+   *
+   * @var string
+   */
+  protected $profile = 'standard';
+
+  /**
+   * Tests skipping setting non translatable metadata fields.
+   */
+  public function testSkipUntranslatable() {
+    $this->drupalLogin($this->translator);
+    $entity_manager = \Drupal::entityManager();
+    $fields = $entity_manager->getFieldDefinitions($this->entityTypeId, $this->bundle);
+
+    // Turn off translatability for the metadata fields on the current bundle.
+    $metadata_fields = ['created', 'changed', 'uid', 'status'];
+    foreach ($metadata_fields as $field_name) {
+      $fields[$field_name]
+        ->getConfig($this->bundle)
+        ->setTranslatable(FALSE)
+        ->save();
+    }
+
+    // Create a new test entity with original values in the default language.
+    $default_langcode = $this->langcodes[0];
+    $entity_id = $this->createEntity([], $default_langcode);
+    $storage = $entity_manager->getStorage($this->entityTypeId);
+    $storage->resetCache();
+    $entity = $storage->load($entity_id);
+
+    // Add a content translation.
+    $langcode = 'it';
+    $values = $entity->toArray();
+    // Apply a default value for the metadata fields.
+    foreach ($metadata_fields as $field_name) {
+      unset($values[$field_name]);
+    }
+    $entity->addTranslation($langcode, $values);
+
+    $metadata_source_translation = $this->manager->getTranslationMetadata($entity->getTranslation($default_langcode));
+    $metadata_target_translation = $this->manager->getTranslationMetadata($entity->getTranslation($langcode));
+
+    $created_time = $metadata_source_translation->getCreatedTime();
+    $changed_time = $metadata_source_translation->getChangedTime();
+    $published = $metadata_source_translation->isPublished();
+    $author = $metadata_source_translation->getAuthor();
+
+    $this->assertEqual($created_time, $metadata_target_translation->getCreatedTime(), 'Metadata created field has the same value for both translations.');
+    $this->assertEqual($changed_time, $metadata_target_translation->getChangedTime(), 'Metadata changed field has the same value for both translations.');
+    $this->assertEqual($published, $metadata_target_translation->isPublished(), 'Metadata published field has the same value for both translations.');
+    $this->assertEqual($author->id(), $metadata_target_translation->getAuthor()->id(), 'Metadata author field has the same value for both translations.');
+
+    $metadata_target_translation->setCreatedTime(time() + 50);
+    $metadata_target_translation->setChangedTime(time() + 50);
+    $metadata_target_translation->setPublished(TRUE);
+    $metadata_target_translation->setAuthor($this->editor);
+
+    $this->assertEqual($created_time, $metadata_target_translation->getCreatedTime(), 'Metadata created field correctly not updated');
+    $this->assertEqual($changed_time, $metadata_target_translation->getChangedTime(), 'Metadata changed field correctly not updated');
+    $this->assertEqual($published, $metadata_target_translation->isPublished(), 'Metadata published field correctly not updated');
+    $this->assertEqual($author->id(), $metadata_target_translation->getAuthor()->id(), 'Metadata author field correctly not updated');
+  }
+
+  /**
+   * Tests setting translatable metadata fields.
+   */
+  public function testSetTranslatable() {
+    $this->drupalLogin($this->translator);
+    $entity_manager = \Drupal::entityManager();
+    $fields = $entity_manager->getFieldDefinitions($this->entityTypeId, $this->bundle);
+
+    // Turn off translatability for the metadata fields on the current bundle.
+    $metadata_fields = ['created', 'changed', 'uid', 'status'];
+    foreach ($metadata_fields as $field_name) {
+      $fields[$field_name]
+        ->getConfig($this->bundle)
+        ->setTranslatable(TRUE)
+        ->save();
+    }
+
+    // Create a new test entity with original values in the default language.
+    $default_langcode = $this->langcodes[0];
+    $entity_id = $this->createEntity(['status' => FALSE], $default_langcode);
+    $storage = $entity_manager->getStorage($this->entityTypeId);
+    $storage->resetCache();
+    $entity = $storage->load($entity_id);
+
+    // Add a content translation.
+    $langcode = 'it';
+    $values = $entity->toArray();
+    // Apply a default value for the metadata fields.
+    foreach ($metadata_fields as $field_name) {
+      unset($values[$field_name]);
+    }
+    $entity->addTranslation($langcode, $values);
+
+    $metadata_source_translation = $this->manager->getTranslationMetadata($entity->getTranslation($default_langcode));
+    $metadata_target_translation = $this->manager->getTranslationMetadata($entity->getTranslation($langcode));
+
+    $metadata_target_translation->setCreatedTime(time() + 50);
+    $metadata_target_translation->setChangedTime(time() + 50);
+    $metadata_target_translation->setPublished(TRUE);
+    $metadata_target_translation->setAuthor($this->editor);
+
+    $this->assertNotEqual($metadata_source_translation->getCreatedTime(), $metadata_target_translation->getCreatedTime(), 'Metadata created field correctly different on both translations.');
+    $this->assertNotEqual($metadata_source_translation->getChangedTime(), $metadata_target_translation->getChangedTime(), 'Metadata changed field correctly different on both translations.');
+    $this->assertNotEqual($metadata_source_translation->isPublished(), $metadata_target_translation->isPublished(), 'Metadata published field correctly different on both translations.');
+    $this->assertNotEqual($metadata_source_translation->getAuthor()->id(), $metadata_target_translation->getAuthor()->id(), 'Metadata author field correctly different on both translations.');
+  }
+}
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
index bf781fb6dde9198482b2787746d98ad52b105b1c..b613937bca496b15b88f3b13a94ad7e580df6382 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
 use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\Component\Utility\SafeMarkup;
 
 /**
  * Tests the Content Translation UI.
@@ -53,7 +54,12 @@ protected function doTestBasicTranslation() {
     // Create a new test entity with original values in the default language.
     $default_langcode = $this->langcodes[0];
     $values[$default_langcode] = $this->getNewEntityValues($default_langcode);
+    // Create the entity with the editor as owner, so that afterwards a new
+    // translation is created by the translator and the translation author is
+    // tested.
+    $this->drupalLogin($this->editor);
     $this->entityId = $this->createEntity($values[$default_langcode], $default_langcode);
+    $this->drupalLogin($this->translator);
     $entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
     $this->assertTrue($entity, 'Entity found in the database.');
     $this->drupalGet($entity->urlInfo());
@@ -80,6 +86,36 @@ protected function doTestBasicTranslation() {
       'target' => $langcode
     ], array('language' => $language));
     $this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), $this->getFormSubmitActionForNewTranslation($entity, $langcode));
+
+    // Get the entity and reset its cache, so that the new translation gets the
+    // updated values.
+    $entity = entity_load($this->entityTypeId, $this->entityId, TRUE);
+    $metadata_source_translation = $this->manager->getTranslationMetadata($entity->getTranslation($default_langcode));
+    $metadata_target_translation = $this->manager->getTranslationMetadata($entity->getTranslation($langcode));
+
+    $author_field_name = $entity->hasField('content_translation_uid') ? 'content_translation_uid' : 'uid';
+    if ($entity->getFieldDefinition($author_field_name)->isTranslatable()) {
+      $this->assertEqual($metadata_target_translation->getAuthor()->id(), $this->translator->id(),
+        SafeMarkup::format('Author of the target translation @langcode correctly stored for translatable owner field.', array('@langcode' => $langcode)));
+
+      $this->assertNotEqual($metadata_target_translation->getAuthor()->id(), $metadata_source_translation->getAuthor()->id(),
+        SafeMarkup::format('Author of the target translation @target different from the author of the source translation @source for translatable owner field.',
+          array('@target' => $langcode, '@source' => $default_langcode)));
+    }
+    else {
+      $this->assertEqual($metadata_target_translation->getAuthor()->id(), $this->editor->id(), 'Author of the entity remained untouched after translation for non translatable owner field.');
+    }
+
+    $created_field_name = $entity->hasField('content_translation_created') ? 'content_translation_created' : 'created';
+    if ($entity->getFieldDefinition($created_field_name)->isTranslatable()) {
+      $this->assertTrue($metadata_target_translation->getCreatedTime() > $metadata_source_translation->getCreatedTime(),
+        SafeMarkup::format('Translation creation timestamp of the target translation @target is newer than the creation timestamp of the source translation @source for translatable created field.',
+          array('@target' => $langcode, '@source' => $default_langcode)));
+    }
+    else {
+      $this->assertEqual($metadata_target_translation->getCreatedTime(), $metadata_source_translation->getCreatedTime(), 'Creation timestamp of the entity remained untouched after translation for non translatable created field.');
+    }
+
     if ($this->testLanguageSelector) {
       $this->assertNoFieldByXPath('//select[@id="edit-langcode-0-value"]', NULL, 'Language selector correctly disabled on translations.');
     }