diff --git entity.api.php entity.api.php
index 42bcb1a..a4b1a17 100644
--- entity.api.php
+++ entity.api.php
@@ -278,6 +278,8 @@ function entity_metadata_hook_entity_info() {
  *       if necessary, e.g. as the data structure is not created yet but one of
  *       its properties is set. See entity_metadata_field_file_callback() for
  *       an example.
+ *     - translatable: (optional) Whether the property is translatable, defaults
+ *       to FALSE.
  *   - bundles: An array keyed by bundle name containing further metadata
  *     related to the bundles only. This array may contain the key 'properties'
  *     with an array of info about the bundle specific properties, structured in
diff --git entity.test entity.test
index 8eebe0e..2112d8a 100644
--- entity.test
+++ entity.test
@@ -325,7 +325,7 @@ class EntityMetadataTestCase extends DrupalWebTestCase {
   }
 
   function setUp() {
-    parent::setUp('entity', 'entity_test');
+    parent::setUp('entity', 'entity_test', 'locale');
     // Create a field having 4 values for testing multiple value support.
     $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
     $this->field = array('field_name' => $this->field_name, 'type' => 'text', 'cardinality' => 4);
@@ -431,6 +431,21 @@ class EntityMetadataTestCase extends DrupalWebTestCase {
     $this->assertEqual($node->body[LANGUAGE_NONE][0]['value'], "<b>The second body.</b>", 'Update appears in the wrapped entity.');
     $this->assert(isset($node->body[LANGUAGE_NONE][0]['safe_value']), 'Formatted text has been processed.');
 
+    // Test translating the body.
+    locale_add_language('de');
+    $wrapper->language('de');
+
+    $languages = language_list();
+    $this->assertEqual($wrapper->getPropertyLanguage(), $languages['de'], 'Wrapper language has been set to German');
+    $this->assertEqual($wrapper->body->value->value(), "<p>The second body.</p>\n", 'Language fallback on neutral language.');
+
+    // Set a German text using the wrapper.
+    $wrapper->body->set(array('value' => "<b>Der zweite Text.</b>"));
+
+    $this->assertEqual($wrapper->body->value->value(), "<p>Der zweite Text.</p>\n", 'German body set and retrieved.');
+    $wrapper->language(NULL);
+    $this->assertEqual($wrapper->body->value->value(), "<p>The second body.</p>\n", 'Language neutral text is still there.');
+
     // Test iterator.
     $type_info = entity_get_property_info('node');
     $this->assertFalse(array_diff_key($type_info['properties'], iterator_to_array($wrapper->getIterator())), 'Iterator is working.');
diff --git includes/entity.wrapper.inc includes/entity.wrapper.inc
index fb155fe..996fffc 100644
--- includes/entity.wrapper.inc
+++ includes/entity.wrapper.inc
@@ -232,7 +232,7 @@ class EntityValueWrapper extends EntityMetadataWrapper {
 class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAggregate {
 
   protected $propertyInfo = array(), $propertyInfoAltered = FALSE;
-  protected $langcode = NULL;
+  protected $langcode = LANGUAGE_NONE;
 
   protected $propertyInfoDefaults = array(
     'type' => 'text',
@@ -314,7 +314,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg
    *   The language code of the language to set.
    * @return EntityWrapper
    */
-  public function language($langcode = NULL) {
+  public function language($langcode = LANGUAGE_NONE) {
     if ($langcode != $this->langcode) {
       $this->langcode = $langcode;
       $this->cache = array();
@@ -331,7 +331,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg
    * @see EntityStructureWrapper::language()
    */
   public function getPropertyLanguage() {
-    if (isset($this->langcode) && $list = language_list()) {
+    if ($this->langcode != LANGUAGE_NONE && $list = language_list()) {
       if (isset($list[$this->langcode])) {
         return $list[$this->langcode];
       }
diff --git modules/callbacks.inc modules/callbacks.inc
index 12a4042..cd7b757 100644
--- modules/callbacks.inc
+++ modules/callbacks.inc
@@ -374,6 +374,9 @@ function entity_metadata_field_property_set($entity, $name, $value, $langcode, $
     $items[$delta][$columns[0]] = $value;
   }
   $entity->{$name}[$langcode] = $items;
+  // Empty the static field language cache, so the field system picks up any
+  // possible new languages.
+  drupal_static_reset('field_language');
 }
 
 /**
@@ -414,6 +417,9 @@ function entity_metadata_field_verbatim_set($entity, $name, $items, $langcode) {
   $field = field_info_field($name);
   $langcode = isset($langcode) ? $langcode : LANGUAGE_NONE;
   $entity->{$name}[$langcode] = $field['cardinality'] == 1 ? array($items) : $items;
+  // Empty the static field language cache, so the field system picks up any
+  // possible new languages.
+  drupal_static_reset('field_language');
 }
 
 /**
diff --git modules/field.info.inc modules/field.info.inc
index d8470b4..bb8b463 100644
--- modules/field.info.inc
+++ modules/field.info.inc
@@ -59,6 +59,7 @@ function entity_metadata_field_default_property_callback(&$info, $entity_type, $
       'setter callback' => 'entity_metadata_field_property_set',
       'access callback' => 'entity_metadata_field_access_callback',
       'query callback' => 'entity_metadata_field_query',
+      'translatable' => !empty($field['translatable']),
       // Specify that this property stems from a field.
       'field' => TRUE,
     );
