diff --git a/inline_entity_form.module b/inline_entity_form.module
index 8f6b69d..9f26d1d 100644
--- a/inline_entity_form.module
+++ b/inline_entity_form.module
@@ -48,6 +48,7 @@ function inline_entity_form_form_alter(&$form, FormStateInterface $form_state, $
     ElementSubmit::attach($form, $form_state);
     WidgetSubmit::attach($form, $form_state);
   }
+  WidgetSubmit::attach($form, $form_state, TRUE);
 }
 
 /**
diff --git a/src/Element/InlineEntityForm.php b/src/Element/InlineEntityForm.php
index 74a7142..7adac71 100644
--- a/src/Element/InlineEntityForm.php
+++ b/src/Element/InlineEntityForm.php
@@ -132,7 +132,6 @@ class InlineEntityForm extends RenderElement {
     }
     // Prepare the entity form and the entity itself for translating.
     $entity_form['#entity'] = TranslationHelper::prepareEntity($entity_form['#entity'], $form_state);
-    $entity_form['#translating'] = TranslationHelper::isTranslating($form_state) && $entity_form['#entity']->isTranslatable();
 
     // Handle revisioning if the entity supports it.
     if ($entity_type->isRevisionable() && $entity_form['#revision']) {
diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php
index 1ddb644..5de26fe 100644
--- a/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php
+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormBase.php
@@ -387,10 +387,8 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
    *   The form state.
    * @param \Drupal\Core\Field\FieldItemListInterface $items
    *   The field values.
-   * @param bool $translating
-   *   Whether there's a translation in progress.
    */
-  protected function prepareFormState(FormStateInterface $form_state, FieldItemListInterface $items, $translating = FALSE) {
+  protected function prepareFormState(FormStateInterface $form_state, FieldItemListInterface $items) {
     $widget_state = $form_state->get(['inline_entity_form', $this->iefId]);
     if (empty($widget_state)) {
       $widget_state = [
@@ -403,10 +401,9 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
       // Store the $items entities in the widget state, for further
       // manipulation.
       foreach ($items->referencedEntities() as $delta => $entity) {
-        // Display the entity in the correct translation.
-        if ($translating) {
-          $entity = TranslationHelper::prepareEntity($entity, $form_state);
-        }
+        // Always display the entity in the correct translation.
+        $entity = TranslationHelper::prepareEntity($entity, $form_state);
+
         $widget_state['entities'][$delta] = [
           'entity' => $entity,
           'weight' => $delta,
@@ -535,6 +532,11 @@ abstract class InlineEntityFormBase extends WidgetBase implements ContainerFacto
     $ief_id = $entity_form['#ief_id'];
     /** @var \Drupal\Core\Entity\EntityInterface $entity */
     $entity = $entity_form['#entity'];
+    // The host langcode might have changed in the meanwhile as it uses an
+    // entity builder.
+    // @see \Drupal\Core\Entity\ContentEntityForm::form()
+    // @see \Drupal\Core\Entity\ContentEntityForm::updateFormLangcode()
+    $entity = TranslationHelper::prepareEntity($entity, $form_state);
 
     if (in_array($entity_form['#op'], ['add', 'duplicate'])) {
       // Determine the correct weight of the new element.
diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php b/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php
index e3fa0cf..0296976 100644
--- a/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php
+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormComplex.php
@@ -241,7 +241,6 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF
     // Determine the wrapper ID for the entire element.
     $wrapper = 'inline-entity-form-' . $this->getIefId();
 
-    $is_translating = $this->isTranslating($form_state);
     $element = [
       '#type' => $this->getSetting('collapsible') ? 'details' : 'fieldset',
       '#tree' => TRUE,
@@ -250,8 +249,7 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF
       '#suffix' => '</div>',
       '#ief_id' => $this->getIefId(),
       '#ief_root' => TRUE,
-      '#translating' => $is_translating,
-      '#allow_asymmetric_translation' => $this->getSetting('allow_asymmetric_translation') || !$is_translating,
+      '#allow_asymmetric_translation' => $this->getSetting('allow_asymmetric_translation') || !$this->isTranslating($form_state),
       '#field_title' => $this->fieldDefinition->getLabel(),
       '#after_build' => [
         [get_class($this), 'removeTranslatabilityClue'],
@@ -262,7 +260,7 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF
       $element['#open'] = $form_state->getUserInput() ?: !$this->getSetting('collapsed');
     }
 
-    $this->prepareFormState($form_state, $items, $element['#translating']);
+    $this->prepareFormState($form_state, $items);
     $entities = $form_state->get([
       'inline_entity_form', $this->getIefId(),
       'entities',
@@ -626,18 +624,42 @@ class InlineEntityFormComplex extends InlineEntityFormBase implements ContainerF
       return;
     }
     $triggering_element = $form_state->getTriggeringElement();
+    $field_name = $this->fieldDefinition->getName();
+    $parents = array_merge($form['#parents'], [$field_name, 'form']);
+    $ief_id = $this->makeIefId($parents);
+
+    // The form might be sent for processing in order to process changing
+    // langcode.
+    // The language code in the form state gets updated only after the main
+    // entity was already fully built, meaning that in the first iteration
+    // we will get the previous language code unless we read it ourselves.
+    $main_entity = $form_state->getFormObject()->getEntity();
+    $main_entity_langcode_key = $main_entity->getEntityType()->getKey('langcode');
+    /** LanguageManger @var $main_entity_langcode_key */
+    if ($main_entity_langcode_key) {
+      $langcode = $form_state->getValue([$main_entity_langcode_key, 0, 'value']);
+      if ($langcode && ($form_state->get('langcode') !== $langcode)) {
+        $entities = [];
+        foreach ($items as $item) {
+          $entities[] = TranslationHelper::prepareEntity($item->entity, $form_state, $langcode);
+        }
+        if (!empty($entities)) {
+          $ief_entities_language_update = $form_state->get('ief_entities_language_update');
+          $ief_entities_language_update[] = $entities;
+          $form_state->set('ief_entities_language_update', $ief_entities_language_update);
+        }
+      }
+    }
+
     if (empty($triggering_element['#ief_submit_trigger'])) {
       return;
     }
 
-    $field_name = $this->fieldDefinition->getName();
-    $parents = array_merge($form['#parents'], [$field_name, 'form']);
-    $ief_id = $this->makeIefId($parents);
     $this->setIefId($ief_id);
     $widget_state = &$form_state->get(['inline_entity_form', $ief_id]);
     foreach ($widget_state['entities'] as $key => $value) {
-      $changed = TranslationHelper::updateEntityLangcode($value['entity'], $form_state);
-      if ($changed) {
+      $value['entity'] = TranslationHelper::prepareEntity($value['entity'], $form_state);
+      if ($value['entity']->isTranslatable() && $value['entity']->isNewTranslation()) {
         $widget_state['entities'][$key]['entity'] = $value['entity'];
         $widget_state['entities'][$key]['needs_save'] = TRUE;
       }
diff --git a/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
index 51e0acc..a83ebf8 100644
--- a/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
@@ -165,7 +165,7 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
       'entities' => [],
     ];
     foreach ($items as $delta => $value) {
-      TranslationHelper::updateEntityLangcode($value->entity, $form_state);
+      $value->entity = TranslationHelper::prepareEntity($value->entity, $form_state);
       $widget_state['entities'][$delta] = [
         'entity' => $value->entity,
         'needs_save' => TRUE,
diff --git a/src/TranslationHelper.php b/src/TranslationHelper.php
index fd5d88c..a044a3e 100644
--- a/src/TranslationHelper.php
+++ b/src/TranslationHelper.php
@@ -17,33 +17,46 @@ class TranslationHelper {
    *   The inline entity.
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   The form state.
+   * @param string|null $form_langcode
+   *   The form language code or NULL to use the form state value.
    *
    * @return \Drupal\Core\Entity\ContentEntityInterface
    *   The prepared entity.
    *
    * @see \Drupal\Core\Entity\ContentEntityForm::initFormLangcodes()
    */
-  public static function prepareEntity(ContentEntityInterface $entity, FormStateInterface $form_state) {
-    $form_langcode = $form_state->get('langcode');
+  public static function prepareEntity(ContentEntityInterface $entity, FormStateInterface $form_state, $form_langcode = NULL) {
+    $form_langcode = $form_langcode ?? $form_state->get('langcode');
     if (empty($form_langcode) || !$entity->isTranslatable()) {
       return $entity;
     }
 
+
     $entity_langcode = $entity->language()->getId();
-    if (self::isTranslating($form_state) && !$entity->hasTranslation($form_langcode)) {
-      // Create a translation from the source language values.
-      $source = $form_state->get(['content_translation', 'source']);
-      $source_langcode = $source ? $source->getId() : $entity_langcode;
-      if (!$entity->hasTranslation($source_langcode)) {
-        $entity->addTranslation($source_langcode, $entity->toArray());
-      }
-      $source_translation = $entity->getTranslation($source_langcode);
-      $entity->addTranslation($form_langcode, $source_translation->toArray());
-      $translation = $entity->getTranslation($form_langcode);
-      $translation->set('content_translation_source', $source_langcode);
-      // Make sure we do not inherit the affected status from the source values.
-      if ($entity->getEntityType()->isRevisionable()) {
-        $translation->setRevisionTranslationAffected(NULL);
+    if (!$entity->hasTranslation($form_langcode)) {
+      // Create a translation from the source language values if we are on a
+      // translation form or use the default translation as a source instead.
+      if (!$entity->hasTranslation($form_langcode)) {
+        // If the entity is new and the form langauge code changed during the
+        // form submission then do not translate but change the language of the
+        // entity.
+        if ($entity->isNew()) {
+          $langcode_key = $entity->getEntityType()->getKey('langcode');
+          $entity->set($langcode_key, $form_langcode);
+        }
+        else {
+          $source = $form_state->get(['content_translation', 'source']);
+          $source_langcode = $source && $entity->hasTranslation($source->getId()) ? $source->getId() : $entity_langcode;
+          $source_translation = $entity->getTranslation($source_langcode);
+          $entity = $entity->addTranslation($form_langcode, $source_translation->toArray());
+          if ($entity->hasField('content_translation_source')) {
+            $entity->set('content_translation_source', $source_langcode);
+          }
+          // Make sure we do not inherit the affected status from the source values.
+          if ($entity->getEntityType()->isRevisionable()) {
+            $entity->setRevisionTranslationAffected(NULL);
+          }
+        }
       }
     }
 
@@ -55,39 +68,6 @@ class TranslationHelper {
     return $entity;
   }
 
-  /**
-   * Updates the entity langcode to match the form langcode.
-   *
-   * Called on submit to allow the user to select a different language through
-   * the langcode form element, which is then transferred to form state.
-   *
-   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
-   *   The entity.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @return bool
-   *   TRUE if the entity langcode was updated, FALSE otherwise.
-   */
-  public static function updateEntityLangcode(ContentEntityInterface $entity, FormStateInterface $form_state) {
-    $changed = FALSE;
-    // This method is first called during form validation, at which point
-    // the 'langcode' form state flag hasn't been updated with the new value.
-    $form_langcode = $form_state->getValue(['langcode', 0, 'value'], $form_state->get('langcode'));
-    if (empty($form_langcode) || !$entity->isTranslatable()) {
-      return $changed;
-    }
-
-    $entity_langcode = $entity->language()->getId();
-    if ($entity_langcode != $form_langcode && !$entity->hasTranslation($form_langcode)) {
-      $langcode_key = $entity->getEntityType()->getKey('langcode');
-      $entity->set($langcode_key, $form_langcode);
-      $changed = TRUE;
-    }
-
-    return $changed;
-  }
-
   /**
    * Determines whether there's a translation in progress.
    *
diff --git a/src/WidgetSubmit.php b/src/WidgetSubmit.php
index 7b1dee5..39a77da 100644
--- a/src/WidgetSubmit.php
+++ b/src/WidgetSubmit.php
@@ -21,12 +21,47 @@ class WidgetSubmit {
    *   The form.
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   The form state.
+   * @param bool $translation_submit
+   *   (optional) A translation submit for the case where the main entity
+   *   changes its language code but the widget is not active.
    */
-  public static function attach(array &$form, FormStateInterface $form_state) {
-    // $form['#ief_element_submit'] runs after the #ief_element_submit
-    // callbacks of all subelements, which means that doSubmit() has
-    // access to the final IEF $form_state.
-    $form['#ief_element_submit'][] = [get_called_class(), 'doSubmit'];
+  public static function attach(array &$form, FormStateInterface $form_state, $translation_submit = FALSE) {
+    if (!$translation_submit) {
+      // $form['#ief_element_submit'] runs after the #ief_element_submit
+      // callbacks of all subelements, which means that doSubmit() has
+      // access to the final IEF $form_state.
+      $form['#ief_element_submit'][] = [get_called_class(), 'doSubmit'];
+    }
+    else {
+      // Entity form actions.
+      foreach (['submit', 'publish', 'unpublish'] as $action) {
+        if (!empty($form['actions'][$action])) {
+          self::addTranslationSubmit($form['actions'][$action], $form);
+        }
+      }
+      // Generic submit button.
+      if (!empty($form['submit'])) {
+        self::addTranslationSubmit($form['submit'], $form);
+      }
+    }
+  }
+
+  /**
+   * Adds the translation submit handler to the given submit element.
+   *
+   * @param array $element
+   *   The submit element.
+   * @param array $complete_form
+   *   The complete form.
+   */
+  public static function addTranslationSubmit(array &$element, array $complete_form) {
+    if (empty($element['#submit'])) {
+      // Drupal runs either the button-level callbacks or the form-level ones.
+      // Having no button-level callbacks indicates that the form has relied
+      // on form-level callbacks, which now need to be transferred.
+      $element['#submit'] = $complete_form['#submit'];
+    }
+    $element['#submit'] = array_merge([[get_called_class(), 'doTranslationSubmit']], $element['#submit']);
   }
 
   /**
@@ -72,4 +107,27 @@ class WidgetSubmit {
     }
   }
 
+  /**
+   * Saves entities as part of a translation submit.
+   *
+   * @param array $form
+   *   The form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
+   */
+  public static function doTranslationSubmit(array $form, FormStateInterface $form_state) {
+    $entities = $form_state->get('ief_entities_language_update') ?? [];
+    if (!empty($entities)) {
+      $referenceUpgrader = new ReferenceUpgrader();
+      foreach ($entities as $entity_group) {
+        foreach ($entity_group as $entity) {
+          $handler = InlineEntityForm::getInlineFormHandler($entity->getEntityTypeId());
+          $referenceUpgrader->upgradeEntityReferences($entity);
+          $handler->save($entity);
+          $referenceUpgrader->registerEntity($entity);
+        }
+      }
+    }
+  }
+
 }
