diff --git a/app/assets/javascripts/issues/list/constants.js b/app/assets/javascripts/issues/list/constants.js
index d4e2cdcfb1d00ed5b4eabbfdf85deef66a0a38ea..4541191730ad54973f06745bedce6380797c1ac5 100644
--- a/app/assets/javascripts/issues/list/constants.js
+++ b/app/assets/javascripts/issues/list/constants.js
@@ -132,6 +132,8 @@ export const TOKEN_TYPE_CONFIDENTIAL = 'confidential';
 export const TOKEN_TYPE_ITERATION = 'iteration';
 export const TOKEN_TYPE_EPIC = 'epic_id';
 export const TOKEN_TYPE_WEIGHT = 'weight';
+export const TOKEN_TYPE_CONTACT = 'crm_contact';
+export const TOKEN_TYPE_ORGANIZATION = 'crm_organization';
 
 export const filters = {
   [TOKEN_TYPE_AUTHOR]: {
@@ -294,4 +296,24 @@ export const filters = {
       },
     },
   },
+  [TOKEN_TYPE_CONTACT]: {
+    [API_PARAM]: {
+      [NORMAL_FILTER]: 'crmContactId',
+    },
+    [URL_PARAM]: {
+      [OPERATOR_IS]: {
+        [NORMAL_FILTER]: 'crm_contact_id',
+      },
+    },
+  },
+  [TOKEN_TYPE_ORGANIZATION]: {
+    [API_PARAM]: {
+      [NORMAL_FILTER]: 'crmOrganizationId',
+    },
+    [URL_PARAM]: {
+      [OPERATOR_IS]: {
+        [NORMAL_FILTER]: 'crm_organization_id',
+      },
+    },
+  },
 };
diff --git a/app/assets/javascripts/issues/list/queries/get_issues.query.graphql b/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
index ec24ea7c56ae08a174d2f1a80bfe245c2b83d05e..dcc0db786b7597dbcf241a62c32deb96172c620c 100644
--- a/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
@@ -20,6 +20,8 @@ query getIssues(
   $releaseTag: [String!]
   $releaseTagWildcardId: ReleaseTagWildcardId
   $types: [IssueType!]
+  $crmContactId: String
+  $crmOrganizationId: String
   $not: NegatedIssueFilterInput
   $beforeCursor: String
   $afterCursor: String
@@ -43,6 +45,8 @@ query getIssues(
       milestoneWildcardId: $milestoneWildcardId
       myReactionEmoji: $myReactionEmoji
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
       before: $beforeCursor
       after: $afterCursor
@@ -76,6 +80,8 @@ query getIssues(
       releaseTag: $releaseTag
       releaseTagWildcardId: $releaseTagWildcardId
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
       before: $beforeCursor
       after: $afterCursor
diff --git a/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql b/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
index 58e7ce32e7c9c54e3b29f12acc8171d84a8fcec6..c1aee772167ea3bc007fb5cfcc60a1f874d851eb 100644
--- a/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
@@ -14,6 +14,8 @@ query getIssuesCount(
   $releaseTag: [String!]
   $releaseTagWildcardId: ReleaseTagWildcardId
   $types: [IssueType!]
+  $crmContactId: String
+  $crmOrganizationId: String
   $not: NegatedIssueFilterInput
 ) {
   group(fullPath: $fullPath) @skip(if: $isProject) {
@@ -32,6 +34,8 @@ query getIssuesCount(
       milestoneWildcardId: $milestoneWildcardId
       myReactionEmoji: $myReactionEmoji
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -50,6 +54,8 @@ query getIssuesCount(
       milestoneWildcardId: $milestoneWildcardId
       myReactionEmoji: $myReactionEmoji
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -68,6 +74,8 @@ query getIssuesCount(
       milestoneWildcardId: $milestoneWildcardId
       myReactionEmoji: $myReactionEmoji
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -90,6 +98,8 @@ query getIssuesCount(
       releaseTag: $releaseTag
       releaseTagWildcardId: $releaseTagWildcardId
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -109,6 +119,8 @@ query getIssuesCount(
       releaseTag: $releaseTag
       releaseTagWildcardId: $releaseTagWildcardId
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -128,6 +140,8 @@ query getIssuesCount(
       releaseTag: $releaseTag
       releaseTagWildcardId: $releaseTagWildcardId
       types: $types
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
diff --git a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
index 432d6f48607f4df75a814cfecd0817316ee979a9..de44dbb26d7f92a8cf1e693d47c7237ae52d60b8 100644
--- a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
+++ b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
@@ -68,6 +68,12 @@ module IssueResolverArguments
              description: 'Negated arguments.',
              prepare: ->(negated_args, ctx) { negated_args.to_h },
              required: false
+    argument :crm_contact_id, GraphQL::Types::String,
+             required: false,
+             description: 'ID of a contact assigned to the issues.'
+    argument :crm_organization_id, GraphQL::Types::String,
+             required: false,
+             description: 'ID of an organization assigned to the issues.'
   end
 
   def resolve_with_lookahead(**args)
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 7467144d5f45c01fc251cba9bcb60463c5306349..6b95f5e83d1bf27f79e4abd8ce755c5ed5423280 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -11578,6 +11578,8 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | <a id="groupissuesconfidential"></a>`confidential` | [`Boolean`](#boolean) | Filter for confidential issues. If "false", excludes confidential issues. If "true", returns only confidential issues. |
 | <a id="groupissuescreatedafter"></a>`createdAfter` | [`Time`](#time) | Issues created after this date. |
 | <a id="groupissuescreatedbefore"></a>`createdBefore` | [`Time`](#time) | Issues created before this date. |
+| <a id="groupissuescrmcontactid"></a>`crmContactId` | [`String`](#string) | ID of a contact assigned to the issues. |
+| <a id="groupissuescrmorganizationid"></a>`crmOrganizationId` | [`String`](#string) | ID of an organization assigned to the issues. |
 | <a id="groupissuesepicid"></a>`epicId` | [`String`](#string) | ID of an epic associated with the issues, "none" and "any" values are supported. |
 | <a id="groupissuesiid"></a>`iid` | [`String`](#string) | IID of the issue. For example, "1". |
 | <a id="groupissuesiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of issues. For example, `["1", "2"]`. |
@@ -14813,6 +14815,8 @@ Returns [`Issue`](#issue).
 | <a id="projectissueconfidential"></a>`confidential` | [`Boolean`](#boolean) | Filter for confidential issues. If "false", excludes confidential issues. If "true", returns only confidential issues. |
 | <a id="projectissuecreatedafter"></a>`createdAfter` | [`Time`](#time) | Issues created after this date. |
 | <a id="projectissuecreatedbefore"></a>`createdBefore` | [`Time`](#time) | Issues created before this date. |
+| <a id="projectissuecrmcontactid"></a>`crmContactId` | [`String`](#string) | ID of a contact assigned to the issues. |
+| <a id="projectissuecrmorganizationid"></a>`crmOrganizationId` | [`String`](#string) | ID of an organization assigned to the issues. |
 | <a id="projectissueepicid"></a>`epicId` | [`String`](#string) | ID of an epic associated with the issues, "none" and "any" values are supported. |
 | <a id="projectissueiid"></a>`iid` | [`String`](#string) | IID of the issue. For example, "1". |
 | <a id="projectissueiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of issues. For example, `["1", "2"]`. |
@@ -14853,6 +14857,8 @@ Returns [`IssueStatusCountsType`](#issuestatuscountstype).
 | <a id="projectissuestatuscountsconfidential"></a>`confidential` | [`Boolean`](#boolean) | Filter for confidential issues. If "false", excludes confidential issues. If "true", returns only confidential issues. |
 | <a id="projectissuestatuscountscreatedafter"></a>`createdAfter` | [`Time`](#time) | Issues created after this date. |
 | <a id="projectissuestatuscountscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Issues created before this date. |
+| <a id="projectissuestatuscountscrmcontactid"></a>`crmContactId` | [`String`](#string) | ID of a contact assigned to the issues. |
+| <a id="projectissuestatuscountscrmorganizationid"></a>`crmOrganizationId` | [`String`](#string) | ID of an organization assigned to the issues. |
 | <a id="projectissuestatuscountsiid"></a>`iid` | [`String`](#string) | IID of the issue. For example, "1". |
 | <a id="projectissuestatuscountsiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of issues. For example, `["1", "2"]`. |
 | <a id="projectissuestatuscountslabelname"></a>`labelName` | [`[String]`](#string) | Labels applied to this issue. |
@@ -14890,6 +14896,8 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | <a id="projectissuesconfidential"></a>`confidential` | [`Boolean`](#boolean) | Filter for confidential issues. If "false", excludes confidential issues. If "true", returns only confidential issues. |
 | <a id="projectissuescreatedafter"></a>`createdAfter` | [`Time`](#time) | Issues created after this date. |
 | <a id="projectissuescreatedbefore"></a>`createdBefore` | [`Time`](#time) | Issues created before this date. |
+| <a id="projectissuescrmcontactid"></a>`crmContactId` | [`String`](#string) | ID of a contact assigned to the issues. |
+| <a id="projectissuescrmorganizationid"></a>`crmOrganizationId` | [`String`](#string) | ID of an organization assigned to the issues. |
 | <a id="projectissuesepicid"></a>`epicId` | [`String`](#string) | ID of an epic associated with the issues, "none" and "any" values are supported. |
 | <a id="projectissuesiid"></a>`iid` | [`String`](#string) | IID of the issue. For example, "1". |
 | <a id="projectissuesiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of issues. For example, `["1", "2"]`. |
diff --git a/ee/app/assets/javascripts/issues/list/queries/get_issues.query.graphql b/ee/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
index 5e88113b0f4f89c77d2c27617e3c7c678ccc0ae8..e89f8eb305d4a2cea10f60ab50c43f49a0a40637 100644
--- a/ee/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
+++ b/ee/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
@@ -24,6 +24,8 @@ query getIssuesEE(
   $iterationId: [ID]
   $iterationWildcardId: IterationWildcardId
   $weight: String
+  $crmContactId: String
+  $crmOrganizationId: String
   $not: NegatedIssueFilterInput
   $beforeCursor: String
   $afterCursor: String
@@ -52,6 +54,8 @@ query getIssuesEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
       before: $beforeCursor
       after: $afterCursor
@@ -93,6 +97,8 @@ query getIssuesEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
       before: $beforeCursor
       after: $afterCursor
diff --git a/ee/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql b/ee/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
index cb687b7f6a009e701449a2ad0a489e850feef61e..7147764714c7406c5cbc77f30ad9a59d41dd1555 100644
--- a/ee/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
+++ b/ee/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
@@ -18,6 +18,8 @@ query getIssuesCountEE(
   $iterationId: [ID]
   $iterationWildcardId: IterationWildcardId
   $weight: String
+  $crmContactId: String
+  $crmOrganizationId: String
   $not: NegatedIssueFilterInput
 ) {
   group(fullPath: $fullPath) @skip(if: $isProject) {
@@ -41,6 +43,8 @@ query getIssuesCountEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -64,6 +68,8 @@ query getIssuesCountEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -87,6 +93,8 @@ query getIssuesCountEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -114,6 +122,8 @@ query getIssuesCountEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -138,6 +148,8 @@ query getIssuesCountEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
@@ -162,6 +174,8 @@ query getIssuesCountEE(
       iterationId: $iterationId
       iterationWildcardId: $iterationWildcardId
       weight: $weight
+      crmContactId: $crmContactId
+      crmOrganizationId: $crmOrganizationId
       not: $not
     ) {
       count
diff --git a/spec/frontend/issues/list/mock_data.js b/spec/frontend/issues/list/mock_data.js
index b1a135ceb1899e50313022e465b1e080a09112ca..46f342cc673663bf3d27ecbf694ebe4c2c86e276 100644
--- a/spec/frontend/issues/list/mock_data.js
+++ b/spec/frontend/issues/list/mock_data.js
@@ -146,6 +146,8 @@ export const locationSearch = [
   'not[epic_id]=34',
   'weight=1',
   'not[weight]=3',
+  'crm_contact_id=123',
+  'crm_organization_id=456',
 ].join('&');
 
 export const locationSearchWithSpecialValues = [
@@ -194,6 +196,8 @@ export const filteredTokens = [
   { type: 'epic_id', value: { data: '34', operator: OPERATOR_IS_NOT } },
   { type: 'weight', value: { data: '1', operator: OPERATOR_IS } },
   { type: 'weight', value: { data: '3', operator: OPERATOR_IS_NOT } },
+  { type: 'crm_contact', value: { data: '123', operator: OPERATOR_IS } },
+  { type: 'crm_organization', value: { data: '456', operator: OPERATOR_IS } },
   { type: 'filtered-search-term', value: { data: 'find' } },
   { type: 'filtered-search-term', value: { data: 'issues' } },
 ];
@@ -222,6 +226,8 @@ export const apiParams = {
   iterationId: ['4', '12'],
   epicId: '12',
   weight: '1',
+  crmContactId: '123',
+  crmOrganizationId: '456',
   not: {
     authorUsername: 'marge',
     assigneeUsernames: ['patty', 'selma'],
@@ -270,6 +276,8 @@ export const urlParams = {
   'not[epic_id]': '34',
   weight: '1',
   'not[weight]': '3',
+  crm_contact_id: '123',
+  crm_organization_id: '456',
 };
 
 export const urlParamsWithSpecialValues = {
diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb
index 81aeee0a3d24023c4bf8980b6d28399cf1b2457c..3569244e5148ff7a074d41dd6156a5ee7b298dd5 100644
--- a/spec/graphql/resolvers/issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/issues_resolver_spec.rb
@@ -389,6 +389,34 @@
         end
       end
 
+      describe 'filtering by crm' do
+        let_it_be(:organization) { create(:organization, group: group) }
+        let_it_be(:contact1) { create(:contact, group: group, organization: organization) }
+        let_it_be(:contact2) { create(:contact, group: group, organization: organization) }
+        let_it_be(:contact3) { create(:contact, group: group) }
+        let_it_be(:crm_issue1) { create(:issue, project: project) }
+        let_it_be(:crm_issue2) { create(:issue, project: project) }
+        let_it_be(:crm_issue3) { create(:issue, project: project) }
+
+        before_all do
+          create(:issue_customer_relations_contact, issue: crm_issue1, contact: contact1)
+          create(:issue_customer_relations_contact, issue: crm_issue2, contact: contact2)
+          create(:issue_customer_relations_contact, issue: crm_issue3, contact: contact3)
+        end
+
+        context 'contact' do
+          it 'returns only the issues for the contact' do
+            expect(resolve_issues({ crm_contact_id: contact1.id })).to contain_exactly(crm_issue1)
+          end
+        end
+
+        context 'organization' do
+          it 'returns only the issues for the contact' do
+            expect(resolve_issues({ crm_organization_id: organization.id })).to contain_exactly(crm_issue1, crm_issue2)
+          end
+        end
+      end
+
       describe 'sorting' do
         context 'when sorting by created' do
           it 'sorts issues ascending' do