diff --git a/phpstan.neon b/phpstan.neon
index 033fbeffbb2d22589d5fa389a28300014d79d784..d19b518b1d183d40054c47b1506592a6c4a1c1ae 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -103,7 +103,7 @@ parameters:
     # @see https://www.drupal.org/project/feeds/issues/3461141
     -
       message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#"
-      count: 3
+      count: 4
       path: src/Plugin/Type/Target/FieldTargetBase.php
 
     # HttpFetcherResult and RawFetcherResult have an optional parameter
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 5516b7e4201d41840eae4592f957e3832f8f4a7c..b13c6d02c1f4bd4f4869b3975ee5a572991be64b 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -16,17 +16,17 @@
     <listener class="\Drupal\Tests\Listeners\DrupalListener">
     </listener>
   </listeners>
-  <!-- Filter for coverage reports. -->
-  <filter>
-    <whitelist>
+  <!-- Settings for coverage reports. -->
+  <coverage>
+    <include>
       <directory>./src</directory>
-      <!-- By definition test classes have no tests. -->
-      <exclude>
-        <directory suffix="Test.php">./</directory>
-        <directory suffix="TestBase.php">./</directory>
-      </exclude>
-    </whitelist>
-  </filter>
+    </include>
+    <!-- By definition test classes have no tests. -->
+    <exclude>
+      <directory suffix="Test.php">./</directory>
+      <directory suffix="TestBase.php">./</directory>
+    </exclude>
+  </coverage>
   <logging>
     <log type="coverage-html" target="coverage" showUncoveredFiles="true"/>
   </logging>
diff --git a/src/Feeds/Target/ConfigEntityReference.php b/src/Feeds/Target/ConfigEntityReference.php
index a7cddf2ea083c61899c64f99cc010b258897cf61..ac9f0e0681cd45de82a1ed10dcfc7baadd5284dc 100644
--- a/src/Feeds/Target/ConfigEntityReference.php
+++ b/src/Feeds/Target/ConfigEntityReference.php
@@ -8,6 +8,7 @@ use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@@ -77,13 +78,16 @@ class ConfigEntityReference extends FieldTargetBase implements ConfigurableTarge
    *   The transliteration manager.
    * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
    *   The manager for managing config schema type plugins.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface|null $field_type_plugin_manager
+   *   (optional) The field type plugin manager. Passing this argument will be
+   *   required in feeds:4.0.0; omitting it is deprecated since feeds:3.1.0.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFinderInterface $entity_finder, TransliterationInterface $transliteration, TypedConfigManagerInterface $typed_config_manager) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFinderInterface $entity_finder, TransliterationInterface $transliteration, TypedConfigManagerInterface $typed_config_manager, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
     $this->entityTypeManager = $entity_type_manager;
     $this->entityFinder = $entity_finder;
     $this->transliteration = $transliteration;
     $this->typedConfigManager = $typed_config_manager;
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $field_type_plugin_manager);
   }
 
   /**
@@ -97,7 +101,8 @@ class ConfigEntityReference extends FieldTargetBase implements ConfigurableTarge
       $container->get('entity_type.manager'),
       $container->get('feeds.entity_finder'),
       $container->get('transliteration'),
-      $container->get('config.typed')
+      $container->get('config.typed'),
+      $container->get('plugin.manager.field.field_type'),
     );
   }
 
diff --git a/src/Feeds/Target/DateTargetBase.php b/src/Feeds/Target/DateTargetBase.php
index 7500cf7a8ed3ec5f0b7d4c90d6b7729b78d35a48..d5edd617b3b032b27a6826ec7ddb606c461b8886 100644
--- a/src/Feeds/Target/DateTargetBase.php
+++ b/src/Feeds/Target/DateTargetBase.php
@@ -5,6 +5,7 @@ namespace Drupal\feeds\Feeds\Target;
 use Drupal\Core\Config\ImmutableConfig;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Datetime\TimeZoneFormHelper;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\feeds\Plugin\Type\Target\ConfigurableTargetInterface;
@@ -34,9 +35,12 @@ abstract class DateTargetBase extends FieldTargetBase implements ConfigurableTar
    *   The plugin definition.
    * @param \Drupal\Core\Config\ImmutableConfig $system_date_config
    *   The system date configuration.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface|null $field_type_plugin_manager
+   *   (optional) The field type plugin manager. Passing this argument will be
+   *   required in feeds:4.0.0; omitting it is deprecated since feeds:3.1.0.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImmutableConfig $system_date_config) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImmutableConfig $system_date_config, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $field_type_plugin_manager);
     $this->systemDateConfig = $system_date_config;
   }
 
@@ -49,6 +53,7 @@ abstract class DateTargetBase extends FieldTargetBase implements ConfigurableTar
       $plugin_id,
       $plugin_definition,
       $container->get('config.factory')->get('system.date'),
+      $container->get('plugin.manager.field.field_type'),
     );
   }
 
diff --git a/src/Feeds/Target/DateTime.php b/src/Feeds/Target/DateTime.php
index b9a7bda608a9d0b8b9c1f11c71a374afee974ac5..2ccd907f2b9ea692d350f56c62145a45444f0ed1 100644
--- a/src/Feeds/Target/DateTime.php
+++ b/src/Feeds/Target/DateTime.php
@@ -3,6 +3,7 @@
 namespace Drupal\feeds\Feeds\Target;
 
 use Drupal\Core\Config\ImmutableConfig;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
 
 /**
@@ -25,8 +26,8 @@ class DateTime extends DateTargetBase {
   /**
    * {@inheritdoc}
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImmutableConfig $system_date_config) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $system_date_config);
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ImmutableConfig $system_date_config, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $system_date_config, $field_type_plugin_manager);
     $this->storageFormat = $this->settings['datetime_type'] === 'date' ? DateTimeItemInterface::DATE_STORAGE_FORMAT : DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
   }
 
diff --git a/src/Feeds/Target/EntityReference.php b/src/Feeds/Target/EntityReference.php
index 4705a34cce18450a70cc90289ac3784235b93abf..66fbc0fccd49776e809d5e28e1b825bc5ce017f4 100644
--- a/src/Feeds/Target/EntityReference.php
+++ b/src/Feeds/Target/EntityReference.php
@@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\TypedData\DataDefinitionInterface;
@@ -69,13 +70,16 @@ class EntityReference extends FieldTargetBase implements ConfigurableTargetInter
    *   The entity field manager.
    * @param \Drupal\feeds\EntityFinderInterface $entity_finder
    *   The Feeds entity finder service.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface|null $field_type_plugin_manager
+   *   (optional) The field type plugin manager. Passing this argument will be
+   *   required in feeds:4.0.0; omitting it is deprecated since feeds:3.1.0.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, EntityFinderInterface $entity_finder) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, EntityFinderInterface $entity_finder, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
     $this->entityTypeManager = $entity_type_manager;
     $this->entityFieldManager = $entity_field_manager;
     $this->entityFinder = $entity_finder;
 
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $field_type_plugin_manager);
   }
 
   /**
@@ -89,6 +93,7 @@ class EntityReference extends FieldTargetBase implements ConfigurableTargetInter
       $container->get('entity_type.manager'),
       $container->get('entity_field.manager'),
       $container->get('feeds.entity_finder'),
+      $container->get('plugin.manager.field.field_type'),
     );
   }
 
diff --git a/src/Feeds/Target/File.php b/src/Feeds/Target/File.php
index b86ad3e47d58185379eabc12bfc84b5442d629ed..f5c248a4928442fa44a7c31f744ed14eb4b4a8f2 100644
--- a/src/Feeds/Target/File.php
+++ b/src/Feeds/Target/File.php
@@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityStorageException;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\File\Exception\FileException;
 use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -97,11 +98,14 @@ class File extends EntityReference {
    *   The file repository.
    * @param \Drupal\Core\Config\ImmutableConfig $file_config
    *   The system.file configuration.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface|null $field_type_plugin_manager
+   *   (optional) The field type plugin manager. Passing this argument will be
+   *   required in feeds:4.0.0; omitting it is deprecated since feeds:3.1.0.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ClientInterface $client, Token $token, EntityFieldManagerInterface $entity_field_manager, EntityFinderInterface $entity_finder, FileSystemInterface $file_system, FileRepositoryInterface $file_repository, ImmutableConfig $file_config) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ClientInterface $client, Token $token, EntityFieldManagerInterface $entity_field_manager, EntityFinderInterface $entity_finder, FileSystemInterface $file_system, FileRepositoryInterface $file_repository, ImmutableConfig $file_config, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
     $this->client = $client;
     $this->token = $token;
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $entity_field_manager, $entity_finder);
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $entity_field_manager, $entity_finder, $field_type_plugin_manager);
     $this->fileExtensions = array_filter(explode(' ', $this->settings['file_extensions']));
     $this->fileSystem = $file_system;
     $this->fileRepository = $file_repository;
@@ -124,6 +128,7 @@ class File extends EntityReference {
       $container->get('file_system'),
       $container->get('file.repository'),
       $container->get('config.factory')->get('system.file'),
+      $container->get('plugin.manager.field.field_type'),
     );
   }
 
diff --git a/src/Feeds/Target/Integer.php b/src/Feeds/Target/Integer.php
index 4c70c22633a12c8131233cf1810618742b8ef37c..25cb6632c0086a8ae89e018e20c25ae602a7495f 100644
--- a/src/Feeds/Target/Integer.php
+++ b/src/Feeds/Target/Integer.php
@@ -34,6 +34,7 @@ class Integer extends Number {
    */
   protected function prepareValue($delta, array &$values) {
     $value = is_string($values['value']) ? trim($values['value']) : $values['value'];
+    $value = $this->convertLabelToKey($value);
     $values['value'] = is_numeric($value) ? (int) $value : '';
   }
 
diff --git a/src/Feeds/Target/Number.php b/src/Feeds/Target/Number.php
index 4b1e9c3d178878cf92041112bd66504c0ccc8249..5c8a32c8d53dafcabd96963a5c6a5c4bfef3f4ab 100644
--- a/src/Feeds/Target/Number.php
+++ b/src/Feeds/Target/Number.php
@@ -43,6 +43,7 @@ class Number extends FieldTargetBase {
    */
   protected function prepareValue($delta, array &$values) {
     $values['value'] = is_string($values['value']) ? trim($values['value']) : $values['value'];
+    $values['value'] = $this->convertLabelToKey($values['value']);
 
     if (!is_numeric($values['value'])) {
       $values['value'] = '';
diff --git a/src/Feeds/Target/Password.php b/src/Feeds/Target/Password.php
index d37d137bf71b5c756d04617c689a93df9cec508e..48ac9ef74795240ed6bd7fb37811a74d5476c39b 100644
--- a/src/Feeds/Target/Password.php
+++ b/src/Feeds/Target/Password.php
@@ -4,6 +4,7 @@ namespace Drupal\feeds\Feeds\Target;
 
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Password\PasswordInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@@ -65,9 +66,12 @@ class Password extends FieldTargetBase implements ConfigurableTargetInterface, C
    *   The password hash service.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface|null $field_type_plugin_manager
+   *   (optional) The field type plugin manager. Passing this argument will be
+   *   required in feeds:4.0.0; omitting it is deprecated since feeds:3.1.0.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, PasswordInterface $password_hasher, ModuleHandlerInterface $module_handler) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, PasswordInterface $password_hasher, ModuleHandlerInterface $module_handler, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $field_type_plugin_manager);
     $this->passwordHasher = $password_hasher;
     $this->moduleHandler = $module_handler;
   }
@@ -87,7 +91,8 @@ class Password extends FieldTargetBase implements ConfigurableTargetInterface, C
       $plugin_id,
       $plugin_definition,
       $password_hasher,
-      $container->get('module_handler')
+      $container->get('module_handler'),
+      $container->get('plugin.manager.field.field_type'),
     );
   }
 
diff --git a/src/Feeds/Target/Text.php b/src/Feeds/Target/Text.php
index 8285abb13eeb5c07aab5c99ad58fa676618dbde6..38914e5615edfabb0dbc00a319fbf48de9b94319 100644
--- a/src/Feeds/Target/Text.php
+++ b/src/Feeds/Target/Text.php
@@ -4,6 +4,7 @@ namespace Drupal\feeds\Feeds\Target;
 
 use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -52,15 +53,18 @@ class Text extends StringTarget implements ConfigurableTargetInterface, Containe
    *   The current user.
    * @param \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $filter_format_storage
    *   The storage for filter_format config entities.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface|null $field_type_plugin_manager
+   *   (optional) The field type plugin manager. Passing this argument will be
+   *   required in feeds:4.0.0; omitting it is deprecated since feeds:3.1.0.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, AccountInterface $user, ?ConfigEntityStorageInterface $filter_format_storage = NULL) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, AccountInterface $user, ?ConfigEntityStorageInterface $filter_format_storage = NULL, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
     $this->user = $user;
     if (!isset($filter_format_storage)) {
       @trigger_error('Calling ' . __METHOD__ . '() without the $filter_format_storage argument is deprecated in feeds:3.0.0-rc2 and will be required in feeds:4.0.0. See https://www.drupal.org/node/3473603', E_USER_DEPRECATED);
       $filter_format_storage = \Drupal::service('entity_type.manager')->getStorage('filter_format');
     }
     $this->filterFormatStorage = $filter_format_storage;
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $field_type_plugin_manager);
   }
 
   /**
diff --git a/src/Plugin/Type/Target/FieldTargetBase.php b/src/Plugin/Type/Target/FieldTargetBase.php
index 9df61ac8238b15f01c8e05f35d2f3297d1c642aa..72f735b436e0a78579f401f4956094003490b89f 100644
--- a/src/Plugin/Type/Target/FieldTargetBase.php
+++ b/src/Plugin/Type/Target/FieldTargetBase.php
@@ -5,6 +5,7 @@ namespace Drupal\feeds\Plugin\Type\Target;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\TranslatableInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
@@ -14,9 +15,11 @@ use Drupal\feeds\FeedInterface;
 use Drupal\feeds\FeedTypeInterface;
 use Drupal\feeds\FieldTargetDefinition;
 use Drupal\feeds\Plugin\Type\Processor\EntityProcessorInterface;
+use Drupal\options\Plugin\Field\FieldType\ListItemBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Helper class for field mappers.
+ * Base class for field mappers.
  */
 abstract class FieldTargetBase extends TargetBase implements ConfigurableTargetInterface, TranslatableTargetInterface {
 
@@ -34,6 +37,51 @@ abstract class FieldTargetBase extends TargetBase implements ConfigurableTargetI
    */
   protected $languageManager;
 
+  /**
+   * The field type plugin manager.
+   *
+   * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
+   */
+  protected $fieldTypePluginManager;
+
+  /**
+   * Constructs a FieldTargetBase instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin ID for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface|null $field_type_plugin_manager
+   *   (optional) The field type plugin manager. Passing this argument will be
+   *   required in feeds:4.0.0; omitting it is deprecated since feeds:3.1.0.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ?FieldTypePluginManagerInterface $field_type_plugin_manager = NULL) {
+    $this->targetDefinition = $configuration['target_definition'];
+    $this->settings = $this->targetDefinition->getFieldDefinition()->getSettings();
+
+    if (!isset($field_type_plugin_manager)) {
+      @trigger_error('Calling ' . __METHOD__ . '() without the $field_type_plugin_manager argument is deprecated in feeds:3.1.0 and will be required in feeds:4.0.0. See https://www.drupal.org/node/3473603', E_USER_DEPRECATED);
+      $field_type_plugin_manager = \Drupal::service('plugin.manager.field.field_type');
+    }
+    $this->fieldTypePluginManager = $field_type_plugin_manager;
+
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('plugin.manager.field.field_type')
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -76,15 +124,6 @@ abstract class FieldTargetBase extends TargetBase implements ConfigurableTargetI
       ->addProperty('value');
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
-    $this->targetDefinition = $configuration['target_definition'];
-    $this->settings = $this->targetDefinition->getFieldDefinition()->getSettings();
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -178,10 +217,43 @@ abstract class FieldTargetBase extends TargetBase implements ConfigurableTargetI
    */
   protected function prepareValue($delta, array &$values) {
     foreach ($values as $column => $value) {
-      $values[$column] = (string) $value;
+      if ($column == 'value') {
+        $values[$column] = $this->convertLabelToKey($value);
+      }
+      else {
+        $values[$column] = (string) $value;
+      }
     }
   }
 
+  /**
+   * For fields with allowed values, allow the source to specify a label.
+   *
+   * @param mixed $value
+   *   The value to look up.
+   *
+   * @return string
+   *   The converted value.
+   */
+  protected function convertLabelToKey($value): string {
+    $allowed_values = $this->getAllowedValues();
+    if (count($allowed_values) > 0 && is_scalar($value)) {
+      if (array_key_exists($value, $allowed_values)) {
+        // It's already a key, allow it as-is.
+        return (string) $value;
+      }
+      else {
+        // Try to match label to key.
+        $key = array_search($value, $allowed_values, TRUE);
+        if ($key !== FALSE) {
+          return (string) $key;
+        }
+      }
+    }
+
+    return (string) $value;
+  }
+
   /**
    * Constructs a base query which is used to find an existing entity.
    *
@@ -434,4 +506,36 @@ abstract class FieldTargetBase extends TargetBase implements ConfigurableTargetI
     return $this->getLanguageManager()->getDefaultLanguage()->getId();
   }
 
+  /**
+   * Determines whether the field is a list field.
+   *
+   * @return bool
+   *   True if the field is a list field, false otherwise.
+   */
+  protected function isListField(): bool {
+    $field_definition = $this->targetDefinition->getFieldDefinition();
+    $field_type_class = $this->fieldTypePluginManager->getDefinition($field_definition->getType())['class'] ?? NULL;
+
+    return is_subclass_of($field_type_class, ListItemBase::class);
+  }
+
+  /**
+   * Get the list of allowed values for this field.
+   *
+   * @return array
+   *   A list of allowed values in an associative array.
+   */
+  protected function getAllowedValues(): array {
+    $allowed_values = [];
+
+    if ($this->isListField()) {
+      $allowed_values = $this->targetDefinition->getFieldDefinition()->getSetting('allowed_values');
+      if (is_callable($allowed_values)) {
+        $allowed_values = call_user_func($allowed_values);
+      }
+    }
+
+    return $allowed_values;
+  }
+
 }
diff --git a/tests/src/Kernel/Feeds/Target/ListTest.php b/tests/src/Kernel/Feeds/Target/ListTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..994218fe2bda538b4304479fa4fce311925c1ba5
--- /dev/null
+++ b/tests/src/Kernel/Feeds/Target/ListTest.php
@@ -0,0 +1,189 @@
+<?php
+
+namespace Drupal\Tests\feeds\Kernel\Feeds\Target;
+
+use Drupal\node\NodeInterface;
+use Drupal\node\Entity\Node;
+use Drupal\Tests\feeds\Kernel\FeedsKernelTestBase;
+
+/**
+ * Tests importing values into list fields using Feeds.
+ *
+ * @group feeds
+ */
+class ListTest extends FeedsKernelTestBase {
+
+  /**
+   * Provides list field types with their allowed values.
+   *
+   * @return array
+   *   Each item contains:
+   *   - field type: 'list_string', 'list_integer', or 'list_float'.
+   *   - allowed values: associative array of allowed keys => labels.
+   */
+  public static function listFieldTypeProvider(): array {
+    return [
+      'List (string)' => [
+        'field_type' => 'list_string',
+        'allowed_values' => ['apple' => 'Apple', 'banana' => 'Banana'],
+      ],
+      'List (integer)' => [
+        'field_type' => 'list_integer',
+        'allowed_values' => [1 => 'One', 2 => 'Two'],
+      ],
+      'List (float)' => [
+        'field_type' => 'list_float',
+        'allowed_values' => ['1.1' => 'Low', '2.2' => 'High'],
+      ],
+    ];
+  }
+
+  /**
+   * Tests importing list values using keys as CSV input.
+   *
+   * @dataProvider listFieldTypeProvider
+   */
+  public function testImportListByKey(string $field_type, array $allowed_values): void {
+    $field_name = 'field_' . $field_type;
+    $expected_key = (string) array_key_first($allowed_values);
+
+    // Create the list field.
+    $this->createFieldWithStorage($field_name, [
+      'type' => $field_type,
+      'storage' => [
+        'settings' => [
+          'allowed_values' => $allowed_values,
+        ],
+      ],
+    ]);
+
+    // Create a feed type.
+    $feed_type = $this->createFeedTypeForCsv([
+      'key_column' => 'Key',
+    ], [
+      'mappings' => array_merge($this->getDefaultMappings(), [
+        [
+          'target' => $field_name,
+          'map' => ['value' => 'key_column'],
+        ],
+      ]),
+    ]);
+
+    // Create a CSV file.
+    $csv_data = "guid,title,key_column\n2,Node with key,$expected_key";
+    $file_path = $this->createCsvFile($csv_data);
+
+    // Import a feed.
+    $feed = $this->createFeed($feed_type->id(), [
+      'source' => $file_path,
+    ]);
+    $feed->import();
+
+    $node = Node::load(1);
+    $this->assertInstanceof(NodeInterface::class, $node, 'Node was created.');
+    $this->assertSame($expected_key, $node->get($field_name)->value);
+  }
+
+  /**
+   * Tests importing an invalid list value (label or key).
+   *
+   * Feeds should ignore or reject values not in the allowed list.
+   *
+   * @dataProvider listFieldTypeProvider
+   */
+  public function testImportInvalidListValue(string $field_type, array $allowed_values): void {
+    $field_name = 'field_' . $field_type;
+
+    $this->createFieldWithStorage($field_name, [
+      'type' => $field_type,
+      'storage' => [
+        'settings' => [
+          'allowed_values' => $allowed_values,
+        ],
+      ],
+    ]);
+
+    $feed_type = $this->createFeedTypeForCsv([
+      'invalid_column' => 'Invalid',
+    ], [
+      'mappings' => array_merge($this->getDefaultMappings(), [
+        [
+          'target' => $field_name,
+          'map' => ['value' => 'invalid_column'],
+        ],
+      ]),
+    ]);
+
+    // Create a CSV file.
+    $csv_data = "guid,title,invalid_column\n3,Node with invalid value,8";
+    $file_path = $this->createCsvFile($csv_data);
+
+    // Import a feed.
+    $feed = $this->createFeed($feed_type->id(), [
+      'source' => $file_path,
+    ]);
+    $feed->import();
+
+    $node = Node::load(1);
+    $this->assertNull($node, 'Node was not created because of validation errors.');
+
+    // Check for the expected validation error.
+    $messages = \Drupal::messenger()->all();
+    foreach ($messages['warning'] as $warning) {
+      $this->assertStringContainsString('The value you selected is not a valid choice.', $warning);
+    }
+
+    // Clear the logged messages so no failure is reported on tear down.
+    $this->logger->clearMessages();
+  }
+
+  /**
+   * Tests importing list values using labels as CSV input.
+   *
+   * @dataProvider listFieldTypeProvider
+   */
+  public function testImportListByLabel(string $field_type, array $allowed_values): void {
+    // Use label value from the allowed values.
+    $import_label = reset($allowed_values);
+    $expected_key = (string) array_search($import_label, $allowed_values, TRUE);
+
+    $field_name = 'field_' . $field_type;
+
+    // Create the list field.
+    $this->createFieldWithStorage($field_name, [
+      'type' => $field_type,
+      'storage' => [
+        'settings' => [
+          'allowed_values' => $allowed_values,
+        ],
+      ],
+    ]);
+
+    // Create a feed type.
+    $feed_type = $this->createFeedTypeForCsv([
+      'label_column' => 'Label',
+    ], [
+      'mappings' => array_merge($this->getDefaultMappings(), [
+        [
+          'target' => $field_name,
+          'map' => ['value' => 'label_column'],
+        ],
+      ]),
+    ]);
+
+    // Create a CSV file.
+    $csv_data = "guid,title,label_column\n1,Node with label,$import_label";
+    $file_path = $this->createCsvFile($csv_data);
+
+    // Import a feed.
+    $feed = $this->createFeed($feed_type->id(), [
+      'source' => $file_path,
+    ]);
+    $feed->import();
+
+    $node = Node::load(1);
+    $this->assertInstanceof(NodeInterface::class, $node, 'Node was created.');
+    $this->assertSame($expected_key, $node->get($field_name)->value);
+  }
+
+}
diff --git a/tests/src/Traits/FeedsCommonTrait.php b/tests/src/Traits/FeedsCommonTrait.php
index 0ddbdf5cf29c96602cdb977735fbb20a30a08fa3..ff143ad015dcf6c1f16ece8ea26165c0f4147859 100644
--- a/tests/src/Traits/FeedsCommonTrait.php
+++ b/tests/src/Traits/FeedsCommonTrait.php
@@ -344,6 +344,25 @@ trait FeedsCommonTrait {
     }
   }
 
+  /**
+   * Creates a CSV file on the public file system.
+   *
+   * @param string $contents
+   *   The contents of the CSV file.
+   *
+   * @return string
+   *   The path to the file that was created.
+   */
+  protected function createCsvFile(string $contents): string {
+    $directory = 'public://feeds_test';
+    $this->container->get('file_system')->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);
+
+    $filename = $directory . '/test.csv';
+    file_put_contents($filename, $contents);
+
+    return $filename;
+  }
+
   /**
    * Prints messages useful for debugging.
    */
diff --git a/tests/src/Unit/Feeds/Target/ConfigEntityReferenceTest.php b/tests/src/Unit/Feeds/Target/ConfigEntityReferenceTest.php
index f2cb86a10a38e6cf26844a8ec5546e027350ba92..d35a53f8086a498d3cd93b803fb0dcaeef4f9328 100644
--- a/tests/src/Unit/Feeds/Target/ConfigEntityReferenceTest.php
+++ b/tests/src/Unit/Feeds/Target/ConfigEntityReferenceTest.php
@@ -40,7 +40,7 @@ class ConfigEntityReferenceTest extends ConfigEntityReferenceTestBase {
       'target_definition' => $this->createTargetDefinitionMock(),
       'reference_by' => 'id',
     ];
-    return new ConfigEntityReference($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->entityFinder->reveal(), $this->transliteration->reveal(), $this->typedConfigManager->reveal());
+    return new ConfigEntityReference($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->entityFinder->reveal(), $this->transliteration->reveal(), $this->typedConfigManager->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/DateRangeTest.php b/tests/src/Unit/Feeds/Target/DateRangeTest.php
index fbdd1df9d674f8bd4c40451ebb59097f1c59117e..680949d89af03e0178e6e3d60e5f984bdb971483 100644
--- a/tests/src/Unit/Feeds/Target/DateRangeTest.php
+++ b/tests/src/Unit/Feeds/Target/DateRangeTest.php
@@ -59,7 +59,7 @@ class DateRangeTest extends DateTestBase {
       'feed_type' => $this->feedType,
       'target_definition' => $this->targetDefinition,
     ];
-    return new DateRange($configuration, static::$pluginId, [], $this->systemDateConfig->reveal());
+    return new DateRange($configuration, static::$pluginId, [], $this->systemDateConfig->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/DateTimeTest.php b/tests/src/Unit/Feeds/Target/DateTimeTest.php
index 028ced3e29883a48a114f2bc19707c8453637dc4..1e5d12c24a0f36291f5e33a68ecfa1328bb9d666 100644
--- a/tests/src/Unit/Feeds/Target/DateTimeTest.php
+++ b/tests/src/Unit/Feeds/Target/DateTimeTest.php
@@ -59,7 +59,7 @@ class DateTimeTest extends DateTestBase {
       'feed_type' => $this->feedType,
       'target_definition' => $this->targetDefinition,
     ];
-    return new DateTime($configuration, static::$pluginId, [], $this->systemDateConfig->reveal());
+    return new DateTime($configuration, static::$pluginId, [], $this->systemDateConfig->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/EntityReferenceTest.php b/tests/src/Unit/Feeds/Target/EntityReferenceTest.php
index 38a3fc04c6a357440bcc9e7f6073d6505d29cfeb..13df924bc3c56a61e1b2f030cd096b9d2545b1a9 100644
--- a/tests/src/Unit/Feeds/Target/EntityReferenceTest.php
+++ b/tests/src/Unit/Feeds/Target/EntityReferenceTest.php
@@ -52,7 +52,7 @@ class EntityReferenceTest extends EntityReferenceTestBase {
       'feed_type' => $this->createMock(FeedTypeInterface::class),
       'target_definition' => $this->createTargetDefinitionMock(),
     ];
-    return new EntityReference($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->entityFieldManager->reveal(), $this->entityFinder->reveal());
+    return new EntityReference($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->entityFieldManager->reveal(), $this->entityFinder->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/FieldTargetTestBase.php b/tests/src/Unit/Feeds/Target/FieldTargetTestBase.php
index 6d6ca098d4e8b470e0b757653e1b626e62852b1a..67d5393383d29c3f829b53753b3ab220ff22f68c 100644
--- a/tests/src/Unit/Feeds/Target/FieldTargetTestBase.php
+++ b/tests/src/Unit/Feeds/Target/FieldTargetTestBase.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\feeds\Unit\Feeds\Target;
 
+use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Tests\feeds\Unit\FeedsUnitTestCase;
 use Drupal\feeds\Exception\EmptyFeedException;
 use Drupal\feeds\FeedTypeInterface;
@@ -20,6 +21,13 @@ abstract class FieldTargetTestBase extends FeedsUnitTestCase {
    */
   protected static $pluginId = '';
 
+  /**
+   * The field type plugin manager.
+   *
+   * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
+   */
+  protected $fieldTypePluginManager;
+
   /**
    * Returns the target class.
    *
@@ -28,6 +36,15 @@ abstract class FieldTargetTestBase extends FeedsUnitTestCase {
    */
   abstract protected function getTargetClass();
 
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp(): void {
+    parent::setUp();
+
+    $this->fieldTypePluginManager = $this->prophesize(FieldTypePluginManagerInterface::class);
+  }
+
   /**
    * Tests the prepareTarget() method.
    */
@@ -65,7 +82,7 @@ abstract class FieldTargetTestBase extends FeedsUnitTestCase {
       'feed_type' => $this->createMock(FeedTypeInterface::class),
       'target_definition' => $method($this->getMockFieldDefinition()),
     ];
-    return new $target_class($configuration, static::$pluginId, []);
+    return new $target_class($configuration, static::$pluginId, [], $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/FileTargetTestBase.php b/tests/src/Unit/Feeds/Target/FileTargetTestBase.php
index cd015eb3d93c808ca9ce2e9c8d66171d1414f98c..dc0efe1edb25cedcf3f8e1c5a0b766c4485093f2 100644
--- a/tests/src/Unit/Feeds/Target/FileTargetTestBase.php
+++ b/tests/src/Unit/Feeds/Target/FileTargetTestBase.php
@@ -114,7 +114,7 @@ abstract class FileTargetTestBase extends FieldTargetTestBase {
       'feed_type' => $this->createMock('Drupal\feeds\FeedTypeInterface'),
       'target_definition' => $method($field_definition_mock),
     ];
-    return new $target_class($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->client->reveal(), $this->token->reveal(), $this->entityFieldManager->reveal(), $this->entityFinder->reveal(), $this->fileSystem->reveal(), $this->fileRepository->reveal(), $this->fileConfig->reveal());
+    return new $target_class($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->client->reveal(), $this->token->reveal(), $this->entityFieldManager->reveal(), $this->entityFinder->reveal(), $this->fileSystem->reveal(), $this->fileRepository->reveal(), $this->fileConfig->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
 }
diff --git a/tests/src/Unit/Feeds/Target/PasswordTest.php b/tests/src/Unit/Feeds/Target/PasswordTest.php
index 6d151bb09d7d83c47cc06cdc00478946f8a9a8f2..a919337e71eafc437ed70e86ee1106293cf2119b 100644
--- a/tests/src/Unit/Feeds/Target/PasswordTest.php
+++ b/tests/src/Unit/Feeds/Target/PasswordTest.php
@@ -63,7 +63,7 @@ class PasswordTest extends FieldTargetTestBase {
       'target_definition' => $method($this->getMockFieldDefinition()),
     ];
 
-    return new Password($configuration, static::$pluginId, [], $this->passwordHasher->reveal(), $this->moduleHandler->reveal());
+    return new Password($configuration, static::$pluginId, [], $this->passwordHasher->reveal(), $this->moduleHandler->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/TelephoneTest.php b/tests/src/Unit/Feeds/Target/TelephoneTest.php
index b99543f7982663612ebd519cf8751d02e4335054..c76fa90f2db161eeb4f7e4f31c4f19b340abef77 100644
--- a/tests/src/Unit/Feeds/Target/TelephoneTest.php
+++ b/tests/src/Unit/Feeds/Target/TelephoneTest.php
@@ -38,7 +38,7 @@ class TelephoneTest extends FieldTargetTestBase {
       'feed_type' => $this->createMock('Drupal\feeds\FeedTypeInterface'),
       'target_definition' => $method($field_definition),
     ];
-    return new Telephone($configuration, static::$pluginId, []);
+    return parent::instantiatePlugin($configuration);
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/TextTest.php b/tests/src/Unit/Feeds/Target/TextTest.php
index b5a6313292d4044206ab3c7a17b19833c55ff6f4..f2221b45ee71784ba968ca1199beb31bf9b1c9f8 100644
--- a/tests/src/Unit/Feeds/Target/TextTest.php
+++ b/tests/src/Unit/Feeds/Target/TextTest.php
@@ -83,6 +83,7 @@ class TextTest extends FieldTargetTestBase {
         [],
         $this->createMock(AccountInterface::class),
         $this->filterFormatStorage->reveal(),
+        $this->fieldTypePluginManager->reveal(),
       ])
       ->onlyMethods(['getFilterFormats'])
       ->getMock();
diff --git a/tests/src/Unit/Feeds/Target/TimestampTest.php b/tests/src/Unit/Feeds/Target/TimestampTest.php
index 2a64af01dc6c5278465eb798562e6f9100f7f848..8f3440f25e4b4eeb61b4bcc8d7b492bedd858288 100644
--- a/tests/src/Unit/Feeds/Target/TimestampTest.php
+++ b/tests/src/Unit/Feeds/Target/TimestampTest.php
@@ -37,7 +37,7 @@ class TimestampTest extends DateTestBase {
       'feed_type' => $this->createMock(FeedTypeInterface::class),
       'target_definition' => $method($this->getMockFieldDefinition()),
     ];
-    return new $target_class($configuration, static::$pluginId, [], $this->systemDateConfig->reveal());
+    return new $target_class($configuration, static::$pluginId, [], $this->systemDateConfig->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/UserRoleTest.php b/tests/src/Unit/Feeds/Target/UserRoleTest.php
index fc8a1a07eba7350d8fa26fc718952f5423aff2d0..0e7d428826fc409d793ffc2a6f39bb8750f5ca0e 100644
--- a/tests/src/Unit/Feeds/Target/UserRoleTest.php
+++ b/tests/src/Unit/Feeds/Target/UserRoleTest.php
@@ -79,7 +79,7 @@ class UserRoleTest extends ConfigEntityReferenceTestBase {
       'target_definition' => $this->createTargetDefinitionMock(),
       'reference_by' => 'label',
     ];
-    return new UserRole($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->entityFinder->reveal(), $this->transliteration->reveal(), $this->typedConfigManager->reveal());
+    return new UserRole($configuration, static::$pluginId, [], $this->entityTypeManager->reveal(), $this->entityFinder->reveal(), $this->transliteration->reveal(), $this->typedConfigManager->reveal(), $this->fieldTypePluginManager->reveal());
   }
 
   /**
diff --git a/tests/src/Unit/Feeds/Target/UuidTest.php b/tests/src/Unit/Feeds/Target/UuidTest.php
index 5bd0be7c056956ff4d28d6e5ccfef9fa550332fd..f8068f086a9e8807af3fb650b11d15be725c01c5 100644
--- a/tests/src/Unit/Feeds/Target/UuidTest.php
+++ b/tests/src/Unit/Feeds/Target/UuidTest.php
@@ -48,7 +48,7 @@ class UuidTest extends FieldTargetTestBase {
       'feed_type' => $this->createMock(FeedTypeInterface::class),
       'target_definition' => $prepareTarget($this->getMockFieldDefinition()),
     ];
-    $target = new Uuid($configuration, 'uuid', []);
+    $target = $this->instantiatePlugin($configuration);
 
     $prepareValue = $this->getProtectedClosure($target, 'prepareValue');
 
@@ -71,7 +71,7 @@ class UuidTest extends FieldTargetTestBase {
       'feed_type' => $this->createMock(FeedTypeInterface::class),
       'target_definition' => $prepareTarget($this->getMockFieldDefinition()),
     ];
-    $target = new Uuid($configuration, 'uuid', []);
+    $target = $this->instantiatePlugin($configuration);
 
     $prepareValue = $this->getProtectedClosure($target, 'prepareValue');