diff --git a/ee/app/assets/javascripts/dependencies/components/filtered_search/group_dependencies_filtered_search.vue b/ee/app/assets/javascripts/dependencies/components/filtered_search/group_dependencies_filtered_search.vue
index 8d43859cdab302b456d244991e42aaf481c54829..a9dd74a9e52515bb427de5867860b2b583602264 100644
--- a/ee/app/assets/javascripts/dependencies/components/filtered_search/group_dependencies_filtered_search.vue
+++ b/ee/app/assets/javascripts/dependencies/components/filtered_search/group_dependencies_filtered_search.vue
@@ -8,6 +8,7 @@ import LicenseToken from './tokens/license_token.vue';
 import ProjectToken from './tokens/project_token.vue';
 import ComponentToken from './tokens/component_token.vue';
 import PackagerToken from './tokens/package_manager_token.vue';
+import VersionToken from './tokens/version_token.vue';
 import DependenciesFilteredSearch from './dependencies_filtered_search.vue';
 
 export default {
@@ -61,6 +62,18 @@ export default {
               },
             ]
           : []),
+        ...(this.glFeatures.versionFilteringOnGroupLevelDependencyList
+          ? [
+              {
+                type: 'version',
+                title: __('Version'),
+                multiSelect: true,
+                unique: true,
+                token: VersionToken,
+                operators: OPERATORS_IS,
+              },
+            ]
+          : []),
       ];
     },
   },
diff --git a/ee/app/assets/javascripts/dependencies/components/filtered_search/project_dependencies_filtered_search.vue b/ee/app/assets/javascripts/dependencies/components/filtered_search/project_dependencies_filtered_search.vue
index a13c8173709b85c8546f96f4a3a4fd4237519a43..bdc0379472a29f20d5bcf5cbac6acd2a308debe4 100644
--- a/ee/app/assets/javascripts/dependencies/components/filtered_search/project_dependencies_filtered_search.vue
+++ b/ee/app/assets/javascripts/dependencies/components/filtered_search/project_dependencies_filtered_search.vue
@@ -1,13 +1,16 @@
 <script>
 import { __ } from '~/locale';
 import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
 import DependenciesFilteredSearch from './dependencies_filtered_search.vue';
 import ComponentToken from './tokens/component_token.vue';
+import VersionToken from './tokens/version_token.vue';
 
 export default {
   components: {
     DependenciesFilteredSearch,
   },
+  mixins: [glFeatureFlagsMixin()],
   computed: {
     tokens() {
       return [
@@ -19,6 +22,18 @@ export default {
           token: ComponentToken,
           operators: OPERATORS_IS,
         },
+        ...(this.glFeatures.versionFilteringOnProjectLevelDependencyList
+          ? [
+              {
+                type: 'version',
+                title: __('Version'),
+                multiSelect: true,
+                unique: true,
+                token: VersionToken,
+                operators: OPERATORS_IS,
+              },
+            ]
+          : []),
       ];
     },
   },
diff --git a/ee/app/assets/javascripts/dependencies/components/filtered_search/tokens/version_token.vue b/ee/app/assets/javascripts/dependencies/components/filtered_search/tokens/version_token.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6b071ae8c693d3a0d53ea9ee308dec89237aeb27
--- /dev/null
+++ b/ee/app/assets/javascripts/dependencies/components/filtered_search/tokens/version_token.vue
@@ -0,0 +1,68 @@
+<script>
+import { GlFilteredSearchToken } from '@gitlab/ui';
+// eslint-disable-next-line no-restricted-imports
+import { mapGetters } from 'vuex';
+
+export default {
+  components: {
+    GlFilteredSearchToken,
+  },
+  props: {
+    config: {
+      type: Object,
+      required: true,
+    },
+    value: {
+      type: Object,
+      required: true,
+    },
+    active: {
+      type: Boolean,
+      required: true,
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    ...mapGetters(['selectedComponents']),
+    tokenValue() {
+      return {
+        ...this.value,
+        // when the token is active (dropdown is open), we set the value to null to prevent an UX issue
+        // in which only the last selected item is being displayed.
+        // more information: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2381
+        data: this.active ? null : [],
+      };
+    },
+    noSelectedComponent() {
+      return this.selectedComponents.length === 0;
+    },
+    multipleSelectedComponents() {
+      return this.selectedComponents.length > 1;
+    },
+    viewOnly() {
+      return this.noSelectedComponent || this.multipleSelectedComponents;
+    },
+  },
+};
+</script>
+
+<template>
+  <gl-filtered-search-token
+    :config="config"
+    v-bind="{ ...$props, ...$attrs }"
+    :value="tokenValue"
+    :view-only="viewOnly"
+    v-on="$listeners"
+  >
+    <template #suggestions>
+      <div v-if="noSelectedComponent" class="gl-p-2 gl-text-secondary">
+        {{ s__('Dependencies|To filter by version, filter by one component first') }}
+      </div>
+      <div v-else-if="multipleSelectedComponents" class="gl-p-2 gl-text-secondary">
+        {{ s__('Dependencies|To filter by version, select exactly one component first') }}
+      </div>
+    </template>
+  </gl-filtered-search-token>
+</template>
diff --git a/ee/app/assets/javascripts/dependencies/store/getters.js b/ee/app/assets/javascripts/dependencies/store/getters.js
index b1994aceea0a8a5145f4a74b9810ab723e14e082..6d8e9d2d95100790d08be96b1fb904a464a4720f 100644
--- a/ee/app/assets/javascripts/dependencies/store/getters.js
+++ b/ee/app/assets/javascripts/dependencies/store/getters.js
@@ -8,3 +8,6 @@ export const totals = (state) =>
     }),
     {},
   );
+
+export const selectedComponents = ({ currentList, ...state }) =>
+  state[currentList].searchFilterParameters.component_names || [];
diff --git a/ee/spec/frontend/dependencies/components/filtered_search/group_dependencies_filtered_search_spec.js b/ee/spec/frontend/dependencies/components/filtered_search/group_dependencies_filtered_search_spec.js
index 329610d730e345bab5cc9906c435a58084e28de4..49636f140dc12c211e7ea29bae680143a734aed0 100644
--- a/ee/spec/frontend/dependencies/components/filtered_search/group_dependencies_filtered_search_spec.js
+++ b/ee/spec/frontend/dependencies/components/filtered_search/group_dependencies_filtered_search_spec.js
@@ -6,6 +6,7 @@ import LicenseToken from 'ee/dependencies/components/filtered_search/tokens/lice
 import ProjectToken from 'ee/dependencies/components/filtered_search/tokens/project_token.vue';
 import PackagerToken from 'ee/dependencies/components/filtered_search/tokens/package_manager_token.vue';
 import ComponentToken from 'ee/dependencies/components/filtered_search/tokens/component_token.vue';
+import VersionToken from 'ee/dependencies/components/filtered_search/tokens/version_token.vue';
 
 describe('GroupDependenciesFilteredSearch', () => {
   let wrapper;
@@ -21,6 +22,7 @@ describe('GroupDependenciesFilteredSearch', () => {
         belowGroupLimit: true,
         glFeatures: {
           groupLevelDependenciesFilteringByPackager: true,
+          versionFilteringOnGroupLevelDependencyList: true,
         },
         ...provide,
       },
@@ -56,6 +58,7 @@ describe('GroupDependenciesFilteredSearch', () => {
       ${'Project'}   | ${{ title: 'Project', type: 'project_ids', multiSelect: true, token: ProjectToken }}
       ${'Packager'}  | ${{ title: 'Packager', type: 'package_managers', multiSelect: true, token: PackagerToken }}
       ${'Component'} | ${{ title: 'Component', type: 'component_names', multiSelect: true, token: ComponentToken }}
+      ${'Version'}   | ${{ title: 'Version', type: 'version', multiSelect: true, token: VersionToken }}
     `('contains a "$tokenTitle" search token', ({ tokenConfig }) => {
       expect(findDependenciesFilteredSearch().props('tokens')).toMatchObject(
         expect.arrayContaining([
@@ -67,8 +70,8 @@ describe('GroupDependenciesFilteredSearch', () => {
     });
   });
 
-  describe('when group_leven_dependencies_filtering_by_packager feature flag is disabled', () => {
-    it('does not contain a "Packager" search token when the feature flag is not enabled', () => {
+  describe('when group_level_dependencies_filtering_by_packager feature flag is disabled', () => {
+    it('does not contain a "Packager" search token', () => {
       createComponent({
         provide: {
           belowGroupLimit: true,
@@ -89,6 +92,28 @@ describe('GroupDependenciesFilteredSearch', () => {
     });
   });
 
+  describe('when version_filtering_on_group_level_dependency_list feature flag is disabled', () => {
+    it('does not contain a "Version" token', () => {
+      createComponent({
+        provide: {
+          belowGroupLimit: true,
+          glFeatures: { versionFilteringOnGroupLevelDependencyList: false },
+        },
+      });
+
+      expect(findDependenciesFilteredSearch().props('tokens')).not.toMatchObject(
+        expect.arrayContaining([
+          expect.objectContaining({
+            title: 'Version',
+            type: 'version',
+            multiSelect: true,
+            token: VersionToken,
+          }),
+        ]),
+      );
+    });
+  });
+
   describe('when sub-group limit-count is reached', () => {
     beforeEach(() => {
       createComponent({
diff --git a/ee/spec/frontend/dependencies/components/filtered_search/project_dependencies_filtered_search_spec.js b/ee/spec/frontend/dependencies/components/filtered_search/project_dependencies_filtered_search_spec.js
index 979c5b37763701682b664c68930f4c5de09f02e2..24c513a4a598313f3c324fdab0cceb0d8e8a86d9 100644
--- a/ee/spec/frontend/dependencies/components/filtered_search/project_dependencies_filtered_search_spec.js
+++ b/ee/spec/frontend/dependencies/components/filtered_search/project_dependencies_filtered_search_spec.js
@@ -2,12 +2,20 @@ import { shallowMount } from '@vue/test-utils';
 import ProjectDependenciesFilteredSearch from 'ee/dependencies/components/filtered_search/project_dependencies_filtered_search.vue';
 import DependenciesFilteredSearch from 'ee/dependencies/components/filtered_search/dependencies_filtered_search.vue';
 import ComponentToken from 'ee/dependencies/components/filtered_search/tokens/component_token.vue';
+import VersionToken from 'ee/dependencies/components/filtered_search/tokens/version_token.vue';
 
 describe('ProjectDependenciesFilteredSearch', () => {
   let wrapper;
 
-  const createComponent = () => {
-    wrapper = shallowMount(ProjectDependenciesFilteredSearch);
+  const createComponent = ({ provide = {} } = {}) => {
+    wrapper = shallowMount(ProjectDependenciesFilteredSearch, {
+      provide: {
+        glFeatures: {
+          versionFilteringOnProjectLevelDependencyList: true,
+        },
+        ...provide,
+      },
+    });
   };
 
   const findDependenciesFilteredSearch = () => wrapper.findComponent(DependenciesFilteredSearch);
@@ -25,6 +33,7 @@ describe('ProjectDependenciesFilteredSearch', () => {
   it.each`
     tokenTitle     | tokenConfig
     ${'Component'} | ${{ title: 'Component', type: 'component_names', multiSelect: true, token: ComponentToken }}
+    ${'Version'}   | ${{ title: 'Version', type: 'version', multiSelect: true, token: VersionToken }}
   `('contains a "$tokenTitle" search token', ({ tokenConfig }) => {
     expect(findDependenciesFilteredSearch().props('tokens')).toMatchObject(
       expect.arrayContaining([
@@ -34,4 +43,25 @@ describe('ProjectDependenciesFilteredSearch', () => {
       ]),
     );
   });
+
+  describe('when version_filtering_on_project_level_dependency_list feature flag is disabled', () => {
+    it('does not contain a "Version" token', () => {
+      createComponent({
+        provide: {
+          glFeatures: { versionFilteringOnProjectLevelDependencyList: false },
+        },
+      });
+
+      expect(findDependenciesFilteredSearch().props('tokens')).not.toMatchObject(
+        expect.arrayContaining([
+          expect.objectContaining({
+            title: 'Version',
+            type: 'version',
+            multiSelect: true,
+            token: VersionToken,
+          }),
+        ]),
+      );
+    });
+  });
 });
diff --git a/ee/spec/frontend/dependencies/components/filtered_search/tokens/version_token_spec.js b/ee/spec/frontend/dependencies/components/filtered_search/tokens/version_token_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..d63ba946e8d7625f2bff6a0465c22ff8731bbdac
--- /dev/null
+++ b/ee/spec/frontend/dependencies/components/filtered_search/tokens/version_token_spec.js
@@ -0,0 +1,96 @@
+import { GlFilteredSearchToken } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { stubComponent } from 'helpers/stub_component';
+import VersionToken from 'ee/dependencies/components/filtered_search/tokens/version_token.vue';
+import createStore from 'ee/dependencies/store';
+
+describe('ee/dependencies/components/filtered_search/tokens/version_token.vue', () => {
+  let wrapper;
+  let store;
+
+  const createVuexStore = () => {
+    store = createStore();
+  };
+
+  const createComponent = () => {
+    wrapper = shallowMountExtended(VersionToken, {
+      store,
+      propsData: {
+        config: {
+          multiSelect: true,
+        },
+        value: {},
+        active: false,
+      },
+      stubs: {
+        GlFilteredSearchToken: stubComponent(GlFilteredSearchToken, {
+          template: `<div><slot name="view"></slot><slot name="suggestions"></slot></div>`,
+        }),
+      },
+    });
+  };
+
+  const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
+
+  beforeEach(() => {
+    createVuexStore();
+    createComponent();
+  });
+
+  describe('when the component is initially rendered', () => {
+    it('passes the correct props to the GlFilteredSearchToken', () => {
+      expect(findFilteredSearchToken().props()).toMatchObject({
+        config: { multiSelect: true },
+        value: { data: [] },
+        viewOnly: true,
+        active: false,
+      });
+    });
+  });
+
+  describe('when no components are selected', () => {
+    it('shows the correct guidance message', () => {
+      expect(findFilteredSearchToken().text()).toBe(
+        'To filter by version, filter by one component first',
+      );
+    });
+
+    it('sets viewOnly prop to true', () => {
+      expect(findFilteredSearchToken().props('viewOnly')).toBe(true);
+    });
+  });
+
+  describe('when multiple components are selected', () => {
+    beforeEach(() => {
+      store.state.allDependencies.searchFilterParameters = {
+        component_names: ['component-1', 'component-2'],
+      };
+    });
+
+    it('shows the correct guidance message', () => {
+      expect(findFilteredSearchToken().text()).toBe(
+        'To filter by version, select exactly one component first',
+      );
+    });
+
+    it('sets viewOnly prop to true', () => {
+      expect(findFilteredSearchToken().props('viewOnly')).toBe(true);
+    });
+  });
+
+  describe('when exactly one component is selected', () => {
+    beforeEach(() => {
+      store.state.allDependencies.searchFilterParameters = {
+        component_names: ['component-1'],
+      };
+    });
+
+    it('does not show any guidance messages', () => {
+      expect(findFilteredSearchToken().text()).toBe('');
+    });
+
+    it('sets viewOnly prop to false', () => {
+      expect(findFilteredSearchToken().props('viewOnly')).toBe(false);
+    });
+  });
+});
diff --git a/ee/spec/frontend/dependencies/store/getters_spec.js b/ee/spec/frontend/dependencies/store/getters_spec.js
index 802c815d38a07e7b4c2a60be10b7237462954428..f897331b85608b114f70414b4ac8189c4417ab0f 100644
--- a/ee/spec/frontend/dependencies/store/getters_spec.js
+++ b/ee/spec/frontend/dependencies/store/getters_spec.js
@@ -41,4 +41,31 @@ describe('Dependencies getters', () => {
       });
     });
   });
+
+  describe('selectedComponents', () => {
+    it('returns the `component_name` array in `searchFilterParameters`', () => {
+      const mockComponentNames = ['component-1', 'component-2'];
+      const state = {
+        listFoo: {
+          searchFilterParameters: {
+            component_names: mockComponentNames,
+          },
+        },
+        currentList: 'listFoo',
+      };
+
+      expect(getters.selectedComponents(state)).toEqual(mockComponentNames);
+    });
+
+    it('returns empty array if `component_names` is not set', () => {
+      const state = {
+        listFoo: {
+          searchFilterParameters: {},
+        },
+        currentList: 'listFoo',
+      };
+
+      expect(getters.selectedComponents(state)).toEqual([]);
+    });
+  });
 });
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index e859b64ad12640c386e5366edac46245786b8431..96b3892af3ed065a26b4c62e5ebf741cd538178f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -19972,6 +19972,12 @@ msgstr ""
 msgid "Dependencies|This link will expire in %{number} days."
 msgstr ""
 
+msgid "Dependencies|To filter by version, filter by one component first"
+msgstr ""
+
+msgid "Dependencies|To filter by version, select exactly one component first"
+msgstr ""
+
 msgid "Dependencies|Toggle vulnerability list"
 msgstr ""