diff --git a/entity_translation.admin.inc b/entity_translation.admin.inc
index a341452..5bfac53 100644
--- a/entity_translation.admin.inc
+++ b/entity_translation.admin.inc
@@ -520,3 +520,195 @@ function entity_translation_delete_confirm_submit($form, &$form_state) {
 
   $form_state['redirect'] = "{$handler->getBasePath()}/translate";
 }
+
+/*
+ * Confirm form for changing field translatability.
+ */
+function entity_translation_translatable_form($form, &$form_state, $field_name) {
+  $field = field_info_field($field_name);
+  $t_args = array('%name' => $field_name);
+
+  $warning = t('By submitting this form you will trigger a batch operation.');
+  if ($field['translatable']) {
+    $title = t('Are you sure you want to disable translation for the %name field?', $t_args);
+    $warning .= "<br>" . t("<strong>All the existing translations of this field will be deleted.</strong><br>This action cannot be undone.");
+  }
+  else {
+    $title = t('Are you sure you want to enable translation for the %name field?', $t_args);
+  }
+
+  // We need to keep some information for later processing.
+  $form_state['field'] = $field;
+
+  return confirm_form($form, $title, '', $warning);
+}
+
+/**
+ * Submit handler for the field settings form.
+ *
+ * This submit handler maintains consistency between the translatability of an
+ * entity and the language under which the field data is stored. When a field is
+ * marked as translatable, all the data in $entity->{field_name}[LANGUAGE_NONE]
+ * is moved to $entity->{field_name}[$entity_language]. When a field is marked
+ * as untranslatable the opposite process occurs. Note that marking a field as
+ * untranslatable will cause all of its translations to be permanently removed,
+ * with the exception of the one corresponding to the entity language.
+ */
+function entity_translation_translatable_form_submit($form, $form_state) {
+  // This is the current state that we want to reverse.
+  $translatable = $form_state['field']['translatable'];
+  $field_name = $form_state['field']['field_name'];
+  $field = field_info_field($field_name);
+
+  if ($field['translatable'] !== $translatable) {
+    // Field translatability has changed since form creation, abort.
+    return;
+  }
+
+  // If a field is untranslatable, it can have no data except under
+  // LANGUAGE_NONE. Thus we need a field to be translatable before we convert
+  // data to the entity language. Conversely we need to switch data back to
+  // LANGUAGE_NONE before making a field untranslatable lest we lose
+  // information.
+  $operations = array(
+    array('entity_translation_translatable_batch', array(!$translatable, $field_name)),
+    array('entity_translation_translatable_switch', array(!$translatable, $field_name)),
+  );
+  $operations = $translatable ? $operations : array_reverse($operations);
+
+  $t_args = array('%field' => $field_name);
+  $title = !$translatable ? t('Enabling translation for the %field field .', $t_args) : t('Disabling translation for the %field field .', $t_args);
+
+  $batch = array(
+    'title' => $title,
+    'operations' => $operations,
+    'finished' => 'entity_translation_translatable_batch_done',
+    'file' => drupal_get_path('module', 'entity_translation') . '/entity_translation.admin.inc',
+  );
+
+  batch_set($batch);
+}
+
+/*
+ * Toggle translatability of the given field.
+ *
+ * This is called from a batch operation, but should only run once per field.
+ */
+function entity_translation_translatable_switch($translatable, $field_name) {
+  $field = field_info_field($field_name);
+
+  if ($field['translatable'] === $translatable) {
+    return;
+  }
+
+  $field['translatable'] = $translatable;
+  field_update_field($field);
+
+  // This is needed for versions of Drupal core 7.10 and lower.
+  // See http://drupal.org/node/1380660 for details.
+  drupal_static_reset('field_available_languages');
+}
+
+/**
+ * Batch operation. Convert field data to or from LANGUAGE_NONE.
+ */
+function entity_translation_translatable_batch($translatable, $field_name, &$context) {
+  if (empty($context['sandbox'])) {
+    $context['sandbox']['progress'] = 0;
+
+    // How many entities will need processing?
+    $query = new EntityFieldQuery();
+    $count = $query
+      ->fieldCondition($field_name)
+      ->count()
+      ->execute();
+
+    if (intval($count) === 0) {
+      // Nothing to do.
+      $context['finished'] = 1;
+      return;
+    }
+    $context['sandbox']['max'] = $count;
+  }
+
+  // Number of entities to be processed for each step.
+  $limit = variable_get('entity_translation_translatable_batch_limit', 10);
+
+  $query = new EntityFieldQuery();
+  $result = $query
+    ->fieldCondition($field_name)
+    ->range($context['sandbox']['progress'], $limit)
+    ->execute();
+
+  foreach ($result as $entity_type => $entities) {
+    foreach (entity_load($entity_type, array_keys($entities)) as $id => $entity) {
+      $context['sandbox']['progress']++;
+      $handler = entity_translation_get_handler($entity_type, $entity);
+      $langcode = $handler->getLanguage();
+
+      // We need a two-steps approach while updating field translations: given
+      // that field-specific update functions might rely on the stored values to
+      // perform their processing, see for instance file_field_update(), first
+      // we need to store the new translations and only after we can remove the
+      // old ones. Otherwise we might have data loss, since the removal of the
+      // old translations might occur before the new ones are stored.
+      if ($translatable && isset($entity->{$field_name}[LANGUAGE_NONE])) {
+        // If the field is being switched to translatable and has data for
+        // LANGUAGE_NONE then we need to move the data to the right language.
+        $entity->{$field_name}[$langcode] = $entity->{$field_name}[LANGUAGE_NONE];
+        // Store the original value.
+        _entity_translation_update_field($entity_type, $entity, $field_name);
+        $entity->{$field_name}[LANGUAGE_NONE] = array();
+        // Remove the language neutral value.
+        _entity_translation_update_field($entity_type, $entity, $field_name);
+      }
+      elseif (!$translatable && isset($entity->{$field_name}[$langcode])) {
+        // The field has been marked untranslatable and has data in the entity
+        // language: we need to move it to LANGUAGE_NONE and drop the other
+        // translations.
+        $entity->{$field_name}[LANGUAGE_NONE] = $entity->{$field_name}[$langcode];
+        // Store the original value.
+        _entity_translation_update_field($entity_type, $entity, $field_name);
+        // Remove translations.
+        foreach ($entity->{$field_name} as $langcode => $items) {
+          if ($langcode != LANGUAGE_NONE) {
+            $entity->{$field_name}[$langcode] = array();
+          }
+        }
+        _entity_translation_update_field($entity_type, $entity, $field_name);
+      }
+      else {
+        // No need to save unchanged entities.
+        continue;
+      }
+    }
+  }
+
+  $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+}
+
+/**
+ * Stores the given field translations.
+ */
+function _entity_translation_update_field($entity_type, $entity, $field_name) {
+  $field = field_info_field($field_name);
+  // Ensure that we are trying to store only valid data.
+  foreach ($entity->{$field_name} as $langcode => $items) {
+    $entity->{$field_name}[$langcode] = _field_filter_items($field, $entity->{$field_name}[$langcode]);
+  }
+  field_attach_presave($entity_type, $entity);
+  field_attach_update($entity_type, $entity);
+}
+
+/**
+ * Check the exit status of the batch operation.
+ */
+function entity_translation_translatable_batch_done($success, $results, $operations) {
+  if ($success) {
+    drupal_set_message(t("Data successfully processed."));
+  }
+  else {
+    // @todo: Do something about this case.
+    drupal_set_message(t("Something went wrong while processing data. Some nodes may appear to have lost fields."));
+  }
+}
diff --git a/entity_translation.module b/entity_translation.module
index 1f0b4bd..b70cc41 100644
--- a/entity_translation.module
+++ b/entity_translation.module
@@ -63,11 +63,17 @@ function entity_translation_entity_info_alter(&$entity_info) {
 
   // Provide defaults for translation info.
   foreach ($entity_info as $entity_type => $info) {
-    if (entity_translation_enabled($entity_type, TRUE)) {
-      if (!isset($entity_info[$entity_type]['translation']['entity_translation'])) {
-        $entity_info[$entity_type]['translation']['entity_translation'] = array();
-      }
+    if (!isset($entity_info[$entity_type]['translation']['entity_translation'])) {
+      $entity_info[$entity_type]['translation']['entity_translation'] = array();
+    }
 
+    // Every fieldable entity type must have a translation handler class, no
+    // matter if it is enabled for translation or not. As a matter of fact we
+    // might need it to correctly switch field translatability when a field is
+    // shared accross different entities.
+    $entity_info[$entity_type]['translation']['entity_translation'] += array('class' => 'EntityTranslationDefaultHandler');
+
+    if (entity_translation_enabled($entity_type, TRUE)) {
       // If no base path is provided we default to the common "node/%node"
       // pattern.
       if (!isset($entity_info[$entity_type]['translation']['entity_translation']['base path'])) {
@@ -80,7 +86,6 @@ function entity_translation_entity_info_alter(&$entity_info) {
 
         // If we cannot find a usable base path we skip to the next entity type.
         if (!isset($router["$entity_type/%"])) {
-          unset($entity_info[$entity_type]['translation']['entity_translation']);
           continue;
         }
 
@@ -93,7 +98,6 @@ function entity_translation_entity_info_alter(&$entity_info) {
       $entity_info[$entity_type]['translation']['entity_translation'] += array(
         'view path' => $path,
         'edit path' => "$path/edit",
-        'class' => 'EntityTranslationDefaultHandler',
         'path wildcard' => "%$entity_type",
         'access callback' => 'entity_translation_tab_access',
         'access arguments' => array($entity_type),
@@ -120,6 +124,24 @@ function entity_translation_enabled($entity_type, $skip_handler = FALSE) {
 }
 
 /**
+ * Implments hook_menu().
+ */
+function entity_translation_menu() {
+  $items = array();
+
+  $items['admin/config/regional/entity_translation/translatable/%'] = array(
+    'title' => 'Confirm change in translatability.',
+    'description' => 'Confirm page for changing field translatability.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('entity_translation_translatable_form', 5),
+    'access arguments' => array('toggle field translatability'),
+    'file' => 'entity_translation.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
  * Implements hook_menu_alter().
  */
 function entity_translation_menu_alter(&$items) {
@@ -211,6 +233,7 @@ function entity_translation_menu_alter(&$items) {
   return $items;
 }
 
+
 /**
  * Implements hook_admin_paths().
  */
@@ -276,6 +299,10 @@ function entity_translation_permission() {
       'title' => t('Administer entity translation'),
       'description' => t('Select which entities can be translated.'),
     ),
+    'toggle field translatability' => array(
+      'title' => t('Toggle field translatability'),
+      'description' => t('Toggle translatability of fields performing a bulk update.'),
+    ),
   );
   foreach (entity_get_info() as $entity_type => $info) {
     if ($info['fieldable']) {
@@ -480,14 +507,39 @@ function entity_translation_edit_form_submit($form, &$form_state) {
  *
  * Enable a selector to choose whether a field is translatable.
  */
-function entity_translation_form_field_ui_field_settings_form_alter(&$form, $form_state) {
-  $instance = $form_state['build_info']['args'][0];
-  $field = field_info_field($instance['field_name']);
-  $form['field']['translatable'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Users may translate this field.'),
-    '#default_value' => $field['translatable'],
-  );
+function entity_translation_form_field_ui_field_edit_form_alter(&$form, $form_state) {
+  $field_name = $form['#field']['field_name'];
+  $field = field_info_field($field_name);
+  $translatable = $field['translatable'];
+  $label = t('Field translation');
+  $title = t('Users may translate this field.');
+
+  if (field_has_data($field)) {
+    $path = "admin/config/regional/entity_translation/translatable/$field_name";
+    $status = $translatable ? $title : t('This field is shared among the entity translations.');
+    $link_title = !$translatable ? t('Enable translation') : t('Disable translation');
+
+    $form['field']['translatable'] = array(
+      '#prefix' => '<div class="translatable"><label>' . $label . '</label>',
+      '#suffix' => '</div>',
+      'message' => array(
+        '#markup' => $status . ' ',
+      ),
+      'link' => array(
+        '#type' => 'link',
+        '#title' => $link_title,
+        '#href' => $path,
+        '#options' => array('query' => drupal_get_destination()),
+        '#access' => user_access('toggle field translatability'),
+      ),
+    );
+  }
+  else {
+    $form['field']['translatable'] = array(
+      '#prefix' => '<label>' . $label . '</label>',
+      '#type' => 'checkbox',
+      '#title' => $title,
+      '#default_value' => $translatable,
+    );
+  }
 }
 
 /**
diff --git a/tests/entity_translation.test b/tests/entity_translation.test
index 08cf41a..3a3a0e2 100644
--- a/tests/entity_translation.test
+++ b/tests/entity_translation.test
@@ -133,26 +133,18 @@ class EntityTranslationTestCase extends DrupalWebTestCase {
   function configureContentType() {
     // Configure the "Basic page" content type to use multilingual support with
     // translation.
-    $this->drupalGet('admin/structure/types/manage/page');
     $edit = array();
     $edit['language_content_type'] = ENTITY_TRANSLATION_ENABLED;
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
 
-    // Set body field's cardinality to unlimited.
-    $this->drupalGet('admin/structure/types/manage/page/fields/body');
+    // Set body field's cardinality to unlimited and toggle translatability.
     $edit = array();
     $edit['field[cardinality]'] = FIELD_CARDINALITY_UNLIMITED;
+    $edit['field[translatable]'] = 1;
     $this->drupalPost('admin/structure/types/manage/page/fields/body', $edit, t('Save settings'));
     $this->assertRaw(t('Saved %field configuration.', array('%field' => 'Body')), t('Body field settings have been updated.'));
 
-    // Set body field to translatable.
-    $this->drupalGet('admin/structure/types/manage/page/fields/body/field-settings');
-    $edit = array();
-    $edit['field[translatable]'] = 1;
-    $this->drupalPost('admin/structure/types/manage/page/fields/body/field-settings', $edit, t('Save field settings'));
-    $this->assertRaw(t('Updated field %field field settings.', array('%field' => 'Body')));
-
     // Check if the setting works.
     $this->drupalGet('node/add/page');
     $this->assertFieldById('edit-body-und-add-more', t('Add another item'), t('Add another item button found.'));
