diff --git a/core/lib/Drupal/Core/Entity/EntityChangedInterface.php b/core/lib/Drupal/Core/Entity/EntityChangedInterface.php
index 747571799cdbc3bdfad084ab1cc4666505cf187f..2c92b0cf431d229100a10cfbb029f2d4aeaaa979 100644
--- a/core/lib/Drupal/Core/Entity/EntityChangedInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityChangedInterface.php
@@ -37,6 +37,11 @@ public function setChangedTime($timestamp);
   /**
    * Gets the timestamp of the last entity change across all translations.
    *
+   * This method will return the highest timestamp across all translations. To
+   * check that no translation is older than in another version of the entity
+   * (e.g. to avoid overwriting newer translations with old data), compare each
+   * translation to the other version individually.
+   *
    * @return int
    *   The timestamp of the last entity save operation across all
    *   translations.
diff --git a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
index b1fee2a29452bf2c290b01053b60aac3f58851e1..28d81ba6e4de28e14401950cfff5198ec37c16fe 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php
@@ -18,10 +18,23 @@ public function validate($entity, Constraint $constraint) {
       /** @var \Drupal\Core\Entity\EntityInterface $entity */
       if (!$entity->isNew()) {
         $saved_entity = \Drupal::entityManager()->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
-        // A change to any other translation must add a violation to the current
-        // translation because there might be untranslatable shared fields.
-        if ($saved_entity && $saved_entity->getChangedTimeAcrossTranslations() > $entity->getChangedTimeAcrossTranslations()) {
-          $this->context->addViolation($constraint->message);
+        // Ensure that all the entity translations are the same as or newer
+        // than their current version in the storage in order to avoid
+        // reverting other changes. In fact the entity object that is being
+        // saved might contain an older entity translation when different
+        // translations are being concurrently edited.
+        if ($saved_entity) {
+          $common_translation_languages = array_intersect_key($entity->getTranslationLanguages(), $saved_entity->getTranslationLanguages());
+          foreach (array_keys($common_translation_languages) as $langcode) {
+            // Merely comparing the latest changed timestamps across all
+            // translations is not sufficient since other translations may have
+            // been edited and saved in the meanwhile. Therefore, compare the
+            // changed timestamps of each entity translation individually.
+            if ($saved_entity->getTranslation($langcode)->getChangedTime() > $entity->getTranslation($langcode)->getChangedTime()) {
+              $this->context->addViolation($constraint->message);
+              break;
+            }
+          }
         }
       }
     }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
index c6461943ec37f518385c349ef6ea1a46eb6059c8..2a6dfed6c2d3590bb1616df09bfac17b6e6908ba 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityValidationTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\KernelTests\Core\Entity;
 
 use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase;
+use Drupal\language\Entity\ConfigurableLanguage;
 
 /**
  * Tests the Entity Validation API.
@@ -16,7 +17,7 @@ class EntityValidationTest extends EntityKernelTestBase {
    *
    * @var array
    */
-  public static $modules = ['filter', 'text'];
+  public static $modules = ['filter', 'text', 'language'];
 
   /**
    * @var string
@@ -39,6 +40,10 @@ class EntityValidationTest extends EntityKernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    // Enable an additional language.
+    ConfigurableLanguage::createFromLangcode('de')
+      ->save();
+
     // Create the test field.
     module_load_install('entity_test');
     entity_test_install();
@@ -200,4 +205,49 @@ public function testCompositeConstraintValidation() {
     $this->assertEqual($constraint->coversFields(), ['name', 'type'], 'Information about covered fields can be retrieved.');
   }
 
+  /**
+   * Tests the EntityChangedConstraintValidator with multiple translations.
+   */
+  public function testEntityChangedConstraintOnConcurrentMultilingualEditing() {
+    $this->installEntitySchema('entity_test_mulrev_changed');
+    $storage = \Drupal::entityTypeManager()
+      ->getStorage('entity_test_mulrev_changed');
+
+    // Create a test entity.
+    $entity = $this->createTestEntity('entity_test_mulrev_changed');
+    $entity->save();
+
+    $entity->setChangedTime($entity->getChangedTime() - 1);
+    $violations = $entity->validate();
+    $this->assertEquals(1, $violations->count());
+    $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+
+    $entity = $storage->loadUnchanged($entity->id());
+    $translation = $entity->addTranslation('de');
+    $entity->save();
+
+    // Ensure that the new translation has a newer changed timestamp than the
+    // default translation.
+    $this->assertGreaterThan($entity->getChangedTime(), $translation->getChangedTime());
+
+    // Simulate concurrent form editing by saving the entity with an altered
+    // non-translatable field in order for the changed timestamp to be updated
+    // across all entity translations.
+    $original_entity_time = $entity->getChangedTime();
+    $entity->set('not_translatable', $this->randomString());
+    $entity->save();
+    // Simulate form submission of an uncached form by setting the previous
+    // timestamp of an entity translation on the saved entity object. This
+    // happens in the entity form API where we put the changed timestamp of
+    // the entity in a form hidden value and then set it on the entity which on
+    // form submit is loaded from the storage if the form is not yet cached.
+    $entity->setChangedTime($original_entity_time);
+    // Setting the changed timestamp from the user input on the entity loaded
+    // from the storage is used as a prevention from saving a form built with a
+    // previous version of the entity and thus reverting changes by other users.
+    $violations = $entity->validate();
+    $this->assertEquals(1, $violations->count());
+    $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+  }
+
 }