diff --git a/core/modules/media/src/Plugin/Field/FieldWidget/MediaImageWidget.php b/core/modules/media/src/Plugin/Field/FieldWidget/MediaImageWidget.php
index 767c4b142d..321aea0f5c 100644
--- a/core/modules/media/src/Plugin/Field/FieldWidget/MediaImageWidget.php
+++ b/core/modules/media/src/Plugin/Field/FieldWidget/MediaImageWidget.php
@@ -83,8 +83,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
   }
 
   /**
-   * Assign the right preview_image_style based on what the user chose, and get
-   * the resulting image's height and width.
+   * If we have an image media entity to work with: add the alt and title fields
+   * if they are required, assign the right preview_image_style, and get the
+   * resulting image's height and width.
    *
    * This method is assigned as a #process callback in formElement() method.
    */
@@ -131,6 +132,12 @@ public static function process($element, FormStateInterface $form_state, $form)
           $media_form_element['alt'] = $dummy_element['alt'];
           $media_form_element['alt']['#weight'] = -5;
         }
+
+        // Same as above, but for title field.
+        if ($title_field && $title_field_required) {
+          $media_form_element['title'] = $dummy_element['title'];
+          $media_form_element['title']['#weight'] = -3;
+        }
       }
 
       // Only show an image preview if we have a style set for it.
@@ -149,18 +156,32 @@ public static function process($element, FormStateInterface $form_state, $form)
     return $element;
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public static function value($element, $input, FormStateInterface $form_state) {
     if (!empty($input['mids'])) {
       $mid = $input['mids'];
       $media_fields_key = 'media_' . $mid;
 
-      if (!empty($input[$media_fields_key]['alt'])) {
-        $media_entity = Media::load($mid);
-        $source_val = $media_entity->get('field_media_image')->getValue();
-        $source_val[0]['alt'] = $input[$media_fields_key]['alt'];
-        $media_entity->set('field_media_image', $source_val);
-        $media_entity->save();
-        unset($input[$media_fields_key]['alt']);
+      // If the "alt" and/or "title" input values are here, it's because the
+      // site builder made them required for this media item's source field
+      // (i.e. an image field).
+      foreach (['alt', 'title'] as $extra_image_field_attribute) {
+        if (!empty($input[$media_fields_key][$extra_image_field_attribute])) {
+          $media_entity = Media::load($mid);
+          $source_field = $media_entity->getSource()
+            ->getSourceFieldDefinition($media_entity->bundle->entity)
+            ->getName();
+          $source_val = $media_entity->get($source_field)->getValue();
+          $source_val[0][$extra_image_field_attribute] = $input[$media_fields_key][$extra_image_field_attribute];
+          $media_entity->set('field_media_image', $source_val);
+          unset($input[$media_fields_key][$extra_image_field_attribute]);
+        }
+
+        if (isset($media_entity)) {
+          $media_entity->save();
+        }
       }
     }
 
