diff --git a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php
index b577c18..8f5e521 100644
--- a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php
+++ b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php
@@ -75,8 +75,10 @@ public function &__get($name) {
     // Allow accessing field values in entity default languages other than
     // LANGUAGE_DEFAULT by mapping the values to LANGUAGE_DEFAULT.
     $langcode = $this->decorated->language()->langcode;
-    if ($langcode != LANGUAGE_DEFAULT && isset($this->decorated->values[$name][LANGUAGE_DEFAULT]) && !isset($this->decorated->values[$name][$langcode])) {
-      $this->decorated->values[$name][$langcode] = &$this->decorated->values[$name][LANGUAGE_DEFAULT];
+    if ($langcode != LANGUAGE_DEFAULT && isset($this->decorated->values[$name]) && is_array($this->decorated->values[$name])) {
+      if (isset($this->decorated->values[$name][LANGUAGE_DEFAULT]) && !isset($this->decorated->values[$name][$langcode])) {
+        $this->decorated->values[$name][$langcode] = &$this->decorated->values[$name][LANGUAGE_DEFAULT];
+      }
     }
 
     if (!isset($this->decorated->values[$name])) {
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index 6c696c3..b5e2ff3 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -19,6 +19,7 @@ function file_field_info() {
         'display_field' => 0,
         'display_default' => 0,
         'uri_scheme' => variable_get('file_default_scheme', 'public'),
+        'translation_sync' => array('fid'),
       ),
       'instance_settings' => array(
         'file_extensions' => 'txt',
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index f739f66..d1b03cd 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -18,6 +18,7 @@ function image_field_info() {
       'settings' => array(
         'uri_scheme' => variable_get('file_default_scheme', 'public'),
         'default_image' => 0,
+        'translation_sync' => array('fid'),
       ),
       'instance_settings' => array(
         'file_extensions' => 'png gif jpg jpeg',
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
index b08518a..dfe87f2 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
@@ -364,6 +364,11 @@ public function entityFormEntityBuild($entity_type, EntityInterface $entity, arr
     if (!empty($values['retranslate'])) {
       $this->retranslate($entity, $form_langcode);
     }
+
+    // Set contextual information that can be reused during the storage phase.
+    $attributes = drupal_container()->get('request')->attributes;
+    $attributes->set('working_langcode', $form_langcode);
+    $attributes->set('source_langcode', $source_langcode);
   }
 
   /**
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncTest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncTest.php
new file mode 100644
index 0000000..9e8bd2c
--- /dev/null
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationSyncTest.php
@@ -0,0 +1,259 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\entity\Tests\EntityTranslationSyncTest.
+ */
+
+namespace Drupal\translation_entity\Tests;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Language\Language;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests the Entity Translation field synchronization capability.
+ */
+class EntityTranslationSyncTest extends WebTestBase {
+
+  /**
+   * The name of the image field to test synchronization on.
+   *
+   * @var string
+   */
+  protected $fieldImageName;
+
+  /**
+   * The cardinality of the image field.
+   *
+   * @var int
+   */
+  protected $cardinality;
+
+  /**
+   * The enabled languages.
+   *
+   * @var array
+   */
+  protected $langcodes;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('language', 'translation_entity', 'entity_test', 'image');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity translation field synchronization',
+      'description' => 'Tests the field synchronization behavior for the test entity.',
+      'group' => 'Entity Translation UI',
+    );
+  }
+
+  /**
+   * Overrides \Drupal\simpletest\WebTestBase::setUp().
+   */
+  function setUp() {
+    parent::setUp();
+
+    // Setup the test image field and the test files.
+    $this->setupImageField();
+    $this->files = $this->drupalGetTestFiles('image');
+
+    // Enable translation for the test entity.
+    translation_entity_set_config('entity_test', 'entity_test', 'enabled', TRUE);
+    drupal_static_reset();
+    entity_info_cache_clear();
+    menu_router_rebuild();
+
+    // Setup the test user.
+    $user = $this->drupalCreateUser(array('administer entity_test content', 'translate any entity'));
+    $this->drupalLogin($user);
+
+    // Setup languages.
+    $this->langcodes = array('it', 'fr');
+    foreach ($this->langcodes as $langcode) {
+      language_save(new Language(array('langcode' => $langcode)));
+    }
+    array_unshift($this->langcodes, language_default()->langcode);
+
+    // Initialize the translation controller.
+    $this->controller = translation_entity_controller('entity_test');
+  }
+
+  /**
+   * Creates the test image field.
+   */
+  protected function setupImageField() {
+    $this->fieldImageName = 'field_test_et_ui_image';
+    $this->cardinality = 3;
+
+    $field = array(
+      'field_name' => $this->fieldImageName,
+      'type' => 'image',
+      'cardinality' => $this->cardinality,
+      'translatable' => TRUE,
+    );
+    field_create_field($field);
+
+    $instance = array(
+      'entity_type' => 'entity_test',
+      'field_name' => $this->fieldImageName,
+      'bundle' => 'entity_test',
+      'label' => 'Test translatable imagefield',
+      'widget' => array(
+        'type' => 'image_image',
+        'weight' => 0,
+      ),
+      'settings' => array(
+        'translation_sync' => TRUE,
+      ),
+    );
+    field_create_instance($instance);
+  }
+
+  /**
+   * Tests entity field synchrnonization.
+   */
+  function testEntitySync() {
+    $default_langcode = $this->langcodes[0];
+    $langcode = $this->langcodes[1];
+
+    // Populate the required contextual values.
+    $attributes = drupal_container()->get('request')->attributes;
+    $attributes->set('working_langcode', $langcode);
+    $attributes->set('source_langcode', $default_langcode);
+
+    // Populate the test entity with some random initial values.
+    $values = array(
+      'name' => $this->randomName(),
+      'user_id' => mt_rand(1, 128),
+      'langcode' => $default_langcode,
+    );
+    $entity = entity_create('entity_test', $values)->getBCEntity();
+
+    // Create some file entities from the generated test files and store them.
+    $values = array();
+    for ($delta = 0; $delta < $this->cardinality; $delta++) {
+      // For the default language use the same order for files and field items.
+      $index = $delta;
+
+      // Create the file entity for the image being processed and record its
+      // identifier.
+      $field_values = array(
+        'uri' => $this->files[$index]->uri,
+        'uid' => $GLOBALS['user']->uid,
+        'status' => FILE_STATUS_PERMANENT,
+      );
+      $file = entity_create('file', $field_values);
+      $file->save();
+      $fid = $file->id();
+      $this->files[$index]->fid = $fid;
+
+      // Generate the item for the current image file entity and attach it to
+      // the entity.
+      $item = array(
+        'fid' => $fid,
+        'alt' => $this->randomName(),
+        'title' => $this->randomName(),
+      );
+      $entity->{$this->fieldImageName}[$default_langcode][$delta] = $item;
+
+      // Store the generated values keying them by fid for easier lookup.
+      $values[$default_langcode][$fid] = $item;
+    }
+    $entity = $this->saveEntity($entity);
+
+    // Create some field translations for the test image field. The translated
+    // items will be one less than the original values to check that only the
+    // translated ones will be preserved. In fact we want the same fids and
+    // items order for both languages.
+    for ($delta = 0; $delta < $this->cardinality - 1; $delta++) {
+      // Simulate a field reordering: items are shifted of one position ahead.
+      // The module ensures we start from the beginning after reaching the
+      // maximum allowed delta.
+      $index = ($delta + 1) % $this->cardinality;
+
+      // Generate the item for the current image file entity and attach it to
+      // the entity.
+      $fid = $this->files[$index]->fid;
+      $item = array(
+        'fid' => $fid,
+        'alt' => $this->randomName(),
+        'title' => $this->randomName(),
+      );
+      $entity->{$this->fieldImageName}[$langcode][$delta] = $item;
+
+      // Again store the generated values keying them by fid for easier lookup.
+      $values[$langcode][$fid] = $item;
+    }
+
+    // Perform synchronization: the translation language is used as source,
+    // while the default langauge is used as target.
+    $entity = $this->saveEntity($entity);
+
+    // Check that one value has been dropped from the original values.
+    $assert = count($entity->{$this->fieldImageName}[$default_langcode]) == 2;
+    $this->assertTrue($assert, 'One item correctly removed from the synchronized field values.');
+
+    // Check that fids have been synchronized and translatable column values
+    // have been retained.
+    $fids = array();
+    foreach ($entity->{$this->fieldImageName}[$default_langcode] as $delta => $item) {
+      $value = $values[$default_langcode][$item['fid']];
+      $source_item = $entity->{$this->fieldImageName}[$langcode][$delta];
+      $assert = $item['fid'] == $source_item['fid'] && $item['alt'] == $value['alt'] && $item['title'] == $value['title'];
+      $this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item['fid'])));
+      $fids[$item['fid']] = TRUE;
+    }
+
+    // Check that the dropped value is the right one.
+    $removed_fid = $this->files[0]->fid;
+    $this->assertTrue(!isset($fids[$removed_fid]), format_string('Field item @fid has been correctly removed.', array('@fid' => $removed_fid)));
+
+    // Add back an item for the dropped value and perform synchronization again.
+    // @todo Actually we would need to reset the contextual information to test
+    //   an update, but there is no entity field class for image fields yet,
+    //   hence field translation update does not work properly for those.
+    $values[$langcode][$removed_fid] = array(
+      'fid' => $removed_fid,
+      'alt' => $this->randomName(),
+      'title' => $this->randomName(),
+    );
+    $entity->{$this->fieldImageName}[$langcode] = array_values($values[$langcode]);
+    $entity = $this->saveEntity($entity);
+
+    // Check that the value has been added to the default language.
+    $assert = count($entity->{$this->fieldImageName}[$default_langcode]) == 3;
+    $this->assertTrue($assert, 'One item correctly added to the synchronized field values.');
+
+    foreach ($entity->{$this->fieldImageName}[$default_langcode] as $delta => $item) {
+      // When adding an item its value is copied over all the target languages,
+      // thus in this case the source language needs to be used to check the
+      // values instead of the target one.
+      $fid_langcode = $item['fid'] != $removed_fid ? $default_langcode : $langcode;
+      $value = $values[$fid_langcode][$item['fid']];
+      $source_item = $entity->{$this->fieldImageName}[$langcode][$delta];
+      $assert = $item['fid'] == $source_item['fid'] && $item['alt'] == $value['alt'] && $item['title'] == $value['title'];
+      $this->assertTrue($assert, format_string('Field item @fid has been successfully synchronized.', array('@fid' => $item['fid'])));
+    }
+  }
+
+  /**
+   * Saves the passed entity and reloads it, enabling compatibility mode.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to be saved.
+   *
+   * @return \Drupal\Core\Entity\EntityInterface
+   *   The saved entity.
+   */
+  protected function saveEntity(EntityInterface $entity) {
+    $entity->save();
+    $entity = entity_test_load($entity->id(), TRUE);
+    return $entity->getBCEntity();
+  }
+
+}
diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module
index b9a2bed..f8ad4bd 100644
--- a/core/modules/translation_entity/translation_entity.module
+++ b/core/modules/translation_entity/translation_entity.module
@@ -634,6 +634,169 @@ function translation_entity_form_field_ui_field_settings_form_alter(array &$form
 }
 
 /**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function translation_entity_form_field_ui_field_edit_form_alter(array &$form, array &$form_state, $form_id) {
+  if ($form['#field']['translatable'] && !empty($form['#field']['settings']['translation_sync'])) {
+    $form['instance']['settings']['translation_sync'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Synchronize translations'),
+      '#description' => t('Check this option if you just wish to translate the textual elements of this field. All the other aspects, such as the order of items or non-textual values, will be the same for all languages.'),
+      '#default_value' => !empty($form['#instance']['settings']['translation_sync']),
+    );
+  }
+}
+
+/**
+ * Implements hook_field_info_alter().
+ */
+function translation_entity_field_info_alter(&$info) {
+  foreach ($info as $field_type => &$field_type_info) {
+    // By default no column has to be synchronized.
+    $field_type_info['settings'] += array('translation_sync' => FALSE);
+    // Synchronization can be enabled per instance.
+    $field_type_info['instance_settings'] += array('translation_sync' => FALSE);
+  }
+}
+
+/**
+ * Implements hook_field_attach_presave().
+ */
+function translation_entity_field_attach_presave($entity_type, $entity) {
+  if (translation_entity_enabled($entity_type, $entity->bundle())) {
+    $attributes = drupal_container()->get('request')->attributes;
+    translation_entity_sync($entity, $attributes->get('working_langcode'), $attributes->get('source_langcode'));
+  }
+}
+
+/**
+ * Performs field column synchronization.
+ *
+ * Field column synchronization takes care of propagating any change in the
+ * field items order and in the column values themselves to all the available
+ * translations. This functionality is provided by defining a 'translation_sync'
+ * key in the field instance settings, holding an array of column names to be
+ * synchronized. The synchronized column values are shared across translations,
+ * while the rest varies per-language. This is useful for instance to translate
+ * the "alt" and "title" textual elements of an image field, while keeping the
+ * same image on every translation.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ *   The entity whose values should be synchronized.
+ * @param $sync_langcode
+ *   The language of the translation whose values should be used as source for
+ *   synchronization.
+ * @param $original_langcode
+ *   (optional) If a new translation is being created, this should be the
+ *   language code of the original values. Defaults to FALSE.
+ */
+function translation_entity_sync(EntityInterface $entity, $sync_langcode, $original_langcode = FALSE) {
+  $translations = $entity->getTranslationLanguages();
+
+  // If we are creating a new entity, or if we have no translations for the
+  // current entity, or we have no information about the translation being
+  // saved, then there is nothing to synchronize.
+  if (empty($sync_langcode) || $entity->isNew() || (count($translations) < 2 && !$original_langcode)) {
+    return;
+  }
+
+  // If the entity language is being changed there is nothing to synchronize.
+  $entity_type = $entity->entityType();
+  $entity_unchanged = isset($entity->original) ? $entity->original : entity_load_unchanged($entity_type, $entity->id());
+  if ($entity->language()->langcode != $entity_unchanged->language()->langcode) {
+    return;
+  }
+
+  // Enable compatibility mode for NG entities.
+  $entity_unchanged = $entity_unchanged->getBCEntity();
+
+  $instances = field_info_instances($entity_type, $entity->bundle());
+  foreach ($instances as $field_name => $instance) {
+    $field = field_info_field($field_name);
+
+    // If the field is empty there is nothing to synchronize. Synchronization
+    // makes sense only for translatable fields.
+    if (!empty($entity->{$field_name}) && !empty($instance['settings']['translation_sync']) && field_is_translatable($entity_type, $field)) {
+      $columns = isset($field['settings']['translation_sync']) ? $field['settings']['translation_sync'] : array();
+      $change_map = array();
+      $source_items = $entity->{$field_name}[$sync_langcode];
+
+      // If a translation is being created, the original values should be used
+      // as the unchanged items. In fact there are no unchanged items to check
+      // against.
+      $langcode = $original_langcode ?: $sync_langcode;
+      $unchanged_items = !empty($entity_unchanged->{$field_name}[$langcode]) ? $entity_unchanged->{$field_name}[$langcode] : array();
+
+      // By picking the maximum size between updated and unchanged items, we
+      // make sure to process also removed items.
+      $total = max(array(count($source_items), count($unchanged_items)));
+
+      // Make sure we can detect any change in the source items.
+      for ($delta = 0; $delta < $total; $delta++) {
+        foreach ($columns as $column) {
+          // Store the delta for the unchanged column value.
+          if (isset($unchanged_items[$delta][$column])) {
+            $value = $unchanged_items[$delta][$column];
+            $change_map[$column][$value]['old'] = $delta;
+          }
+          // Store the delta for the new column value.
+          if (isset($source_items[$delta][$column])) {
+            $value = $source_items[$delta][$column];
+            $change_map[$column][$value]['new'] = $delta;
+          }
+        }
+      }
+
+      // Backup field values.
+      $field_values = $entity->{$field_name};
+
+      // Reset field values so that no spurious value is stored. Source values
+      // must be preserved in any case.
+      $entity->{$field_name} = array($sync_langcode => $source_items);
+
+      // Update translations.
+      foreach ($translations as $langcode => $language) {
+        // We need to synchronize only values different from the source ones.
+        if ($langcode != $sync_langcode) {
+          // Process even removed items.
+          for ($delta = 0; $delta < $total; $delta++) {
+            $created = TRUE;
+            $removed = TRUE;
+
+            foreach ($columns as $column) {
+              if (isset($source_items[$delta][$column])) {
+                $value = $source_items[$delta][$column];
+                $created = $created && !isset($change_map[$column][$value]['old']);
+                $removed = $removed && !isset($change_map[$column][$value]['new']);
+              }
+            }
+
+            // If an item has been removed we do not store its translations.
+            if ($removed) {
+              continue;
+            }
+            // If a synchronized column has changed we need to override the full
+            // items array for all languages.
+            elseif ($created) {
+              $entity->{$field_name}[$langcode][$delta] = $source_items[$delta];
+            }
+            // The current item might have been reordered.
+            elseif (!empty($change_map[$column][$value])) {
+              $old_delta = $change_map[$column][$value]['old'];
+              $new_delta = $change_map[$column][$value]['new'];
+              // If for any reason the old value is not defined for the current
+              // we language we fall back to the new source value.
+              $item = isset($field_values[$langcode][$old_delta]) ? $field_values[$langcode][$old_delta] : $source_items[$new_delta];
+              $entity->{$field_name}[$langcode][$new_delta] = $item;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_element_info_alter().
  */
 function translation_entity_element_info_alter(&$type) {
