diff --git a/app/graphql/resolvers/issues_resolver.rb b/app/graphql/resolvers/issues_resolver.rb
index ae77af32b5b85cb671f0769064f924468f7d23b7..04da54a6bb69fee93a87c67961a8c59f09f46741 100644
--- a/app/graphql/resolvers/issues_resolver.rb
+++ b/app/graphql/resolvers/issues_resolver.rb
@@ -56,12 +56,17 @@ def resolve(**args)
       # The project could have been loaded in batch by `BatchLoader`.
       # At this point we need the `id` of the project to query for issues, so
       # make sure it's loaded and not `nil` before continuing.
-      project = object.respond_to?(:sync) ? object.sync : object
-      return Issue.none if project.nil?
+      parent = object.respond_to?(:sync) ? object.sync : object
+      return Issue.none if parent.nil?
+
+      if parent.is_a?(Group)
+        args[:group_id] = parent.id
+      else
+        args[:project_id] = parent.id
+      end
 
       # Will need to be be made group & namespace aware with
       # https://gitlab.com/gitlab-org/gitlab-foss/issues/54520
-      args[:project_id] = project.id
       args[:iids] ||= [args[:iid]].compact
       args[:attempt_project_search_optimizations] = args[:search].present?
 
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index bd9efef94f8b194253606375e559c778a75c68de..20b4c66ba9510361dec04df85e54fb7c97eb796a 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -43,6 +43,12 @@ class GroupType < NamespaceType
           description: 'Parent group',
           resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, obj.parent_id).find }
 
+    field :issues,
+          Types::IssueType.connection_type,
+          null: true,
+          description: 'Issues of the group',
+          resolver: Resolvers::IssuesResolver
+
     field :milestones, Types::MilestoneType.connection_type, null: true,
           description: 'Find milestones',
           resolver: Resolvers::MilestoneResolver
diff --git a/changelogs/unreleased/197227-graphql-group-milestones.yml b/changelogs/unreleased/197227-graphql-group-milestones.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8acd40ca2f05b7d05bc6ef0c90bba7abb2479081
--- /dev/null
+++ b/changelogs/unreleased/197227-graphql-group-milestones.yml
@@ -0,0 +1,5 @@
+---
+title: Add issues to graphQL group endpoint
+merge_request: 27789
+author:
+type: added
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index ea11a2039212a8eceb46bfdd572122110417e738..0fbd8c84e5800100d0097e59a51717ed84255825 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -3219,6 +3219,106 @@ type Group {
   """
   id: ID!
 
+  """
+  Issues of the group
+  """
+  issues(
+    """
+    Returns the elements in the list that come after the specified cursor.
+    """
+    after: String
+
+    """
+    ID of a user assigned to the issues, "none" and "any" values supported
+    """
+    assigneeId: String
+
+    """
+    Username of a user assigned to the issues
+    """
+    assigneeUsername: String
+
+    """
+    Returns the elements in the list that come before the specified cursor.
+    """
+    before: String
+
+    """
+    Issues closed after this date
+    """
+    closedAfter: Time
+
+    """
+    Issues closed before this date
+    """
+    closedBefore: Time
+
+    """
+    Issues created after this date
+    """
+    createdAfter: Time
+
+    """
+    Issues created before this date
+    """
+    createdBefore: Time
+
+    """
+    Returns the first _n_ elements from the list.
+    """
+    first: Int
+
+    """
+    IID of the issue. For example, "1"
+    """
+    iid: String
+
+    """
+    List of IIDs of issues. For example, [1, 2]
+    """
+    iids: [String!]
+
+    """
+    Labels applied to this issue
+    """
+    labelName: [String]
+
+    """
+    Returns the last _n_ elements from the list.
+    """
+    last: Int
+
+    """
+    Milestones applied to this issue
+    """
+    milestoneTitle: [String]
+
+    """
+    Search query for finding issues by title or description
+    """
+    search: String
+
+    """
+    Sort issues by this criteria
+    """
+    sort: IssueSort = created_desc
+
+    """
+    Current state of this issue
+    """
+    state: IssuableState
+
+    """
+    Issues updated after this date
+    """
+    updatedAfter: Time
+
+    """
+    Issues updated before this date
+    """
+    updatedBefore: Time
+  ): IssueConnection
+
   """
   Indicates if Large File Storage (LFS) is enabled for namespace
   """
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 9e3460c0b03fd7dcf2b329dba0022c7e8731c44b..bd78b51684f36ef11a838134225ebbc3779f7c27 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -9242,6 +9242,225 @@
               "isDeprecated": false,
               "deprecationReason": null
             },
+            {
+              "name": "issues",
+              "description": "Issues of the group",
+              "args": [
+                {
+                  "name": "iid",
+                  "description": "IID of the issue. For example, \"1\"",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "String",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "iids",
+                  "description": "List of IIDs of issues. For example, [1, 2]",
+                  "type": {
+                    "kind": "LIST",
+                    "name": null,
+                    "ofType": {
+                      "kind": "NON_NULL",
+                      "name": null,
+                      "ofType": {
+                        "kind": "SCALAR",
+                        "name": "String",
+                        "ofType": null
+                      }
+                    }
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "state",
+                  "description": "Current state of this issue",
+                  "type": {
+                    "kind": "ENUM",
+                    "name": "IssuableState",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "labelName",
+                  "description": "Labels applied to this issue",
+                  "type": {
+                    "kind": "LIST",
+                    "name": null,
+                    "ofType": {
+                      "kind": "SCALAR",
+                      "name": "String",
+                      "ofType": null
+                    }
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "milestoneTitle",
+                  "description": "Milestones applied to this issue",
+                  "type": {
+                    "kind": "LIST",
+                    "name": null,
+                    "ofType": {
+                      "kind": "SCALAR",
+                      "name": "String",
+                      "ofType": null
+                    }
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "assigneeUsername",
+                  "description": "Username of a user assigned to the issues",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "String",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "assigneeId",
+                  "description": "ID of a user assigned to the issues, \"none\" and \"any\" values supported",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "String",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "createdBefore",
+                  "description": "Issues created before this date",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Time",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "createdAfter",
+                  "description": "Issues created after this date",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Time",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "updatedBefore",
+                  "description": "Issues updated before this date",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Time",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "updatedAfter",
+                  "description": "Issues updated after this date",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Time",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "closedBefore",
+                  "description": "Issues closed before this date",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Time",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "closedAfter",
+                  "description": "Issues closed after this date",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Time",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "search",
+                  "description": "Search query for finding issues by title or description",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "String",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "sort",
+                  "description": "Sort issues by this criteria",
+                  "type": {
+                    "kind": "ENUM",
+                    "name": "IssueSort",
+                    "ofType": null
+                  },
+                  "defaultValue": "created_desc"
+                },
+                {
+                  "name": "after",
+                  "description": "Returns the elements in the list that come after the specified cursor.",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "String",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "before",
+                  "description": "Returns the elements in the list that come before the specified cursor.",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "String",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "first",
+                  "description": "Returns the first _n_ elements from the list.",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Int",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                },
+                {
+                  "name": "last",
+                  "description": "Returns the last _n_ elements from the list.",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "Int",
+                    "ofType": null
+                  },
+                  "defaultValue": null
+                }
+              ],
+              "type": {
+                "kind": "OBJECT",
+                "name": "IssueConnection",
+                "ofType": null
+              },
+              "isDeprecated": false,
+              "deprecationReason": null
+            },
             {
               "name": "lfsEnabled",
               "description": "Indicates if Large File Storage (LFS) is enabled for namespace",
diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb
index 7cfef9b4cc7be395436789dfaae426bf2732b052..4467c228e9614d5e708aeb3b5d3224879892e422 100644
--- a/spec/graphql/resolvers/issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/issues_resolver_spec.rb
@@ -7,15 +7,20 @@
 
   let(:current_user) { create(:user) }
 
-  context "with a project" do
-    let_it_be(:project)   { create(:project) }
-    let_it_be(:milestone) { create(:milestone, project: project) }
-    let_it_be(:assignee)  { create(:user) }
-    let_it_be(:issue1)    { create(:issue, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago, milestone: milestone) }
-    let_it_be(:issue2)    { create(:issue, project: project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago, assignees: [assignee]) }
-    let_it_be(:label1)    { create(:label, project: project) }
-    let_it_be(:label2)    { create(:label, project: project) }
+  let_it_be(:group)         { create(:group) }
+  let_it_be(:project)       { create(:project, group: group) }
+  let_it_be(:other_project) { create(:project, group: group) }
+
+  let_it_be(:milestone) { create(:milestone, project: project) }
+  let_it_be(:assignee)  { create(:user) }
+  let_it_be(:issue1)    { create(:issue, project: project, state: :opened, created_at: 3.hours.ago, updated_at: 3.hours.ago, milestone: milestone) }
+  let_it_be(:issue2)    { create(:issue, project: project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago, assignees: [assignee]) }
+  let_it_be(:issue3)    { create(:issue, project: other_project, state: :closed, title: 'foo', created_at: 1.hour.ago, updated_at: 1.hour.ago, closed_at: 1.hour.ago, assignees: [assignee]) }
+  let_it_be(:issue4)    { create(:issue) }
+  let_it_be(:label1)    { create(:label, project: project) }
+  let_it_be(:label2)    { create(:label, project: project) }
 
+  context "with a project" do
     before do
       project.add_developer(current_user)
       create(:label_link, label: label1, target: issue1)
@@ -184,6 +189,20 @@
     end
   end
 
+  context "with a group" do
+    before do
+      group.add_developer(current_user)
+    end
+
+    describe '#resolve' do
+      it 'finds all group issues' do
+        result = resolve(described_class, obj: group, ctx: { current_user: current_user })
+
+        expect(result).to contain_exactly(issue1, issue2, issue3)
+      end
+    end
+  end
+
   context "when passing a non existent, batch loaded project" do
     let(:project) do
       BatchLoader::GraphQL.for("non-existent-path").batch do |_fake_paths, loader, _|
diff --git a/spec/requests/api/graphql/group_query_spec.rb b/spec/requests/api/graphql/group_query_spec.rb
index a38d1857076dec608c2502ef01011de8f6b39ea2..c7b537a9923df1c188c9e47a511052aea8377c77 100644
--- a/spec/requests/api/graphql/group_query_spec.rb
+++ b/spec/requests/api/graphql/group_query_spec.rb
@@ -51,6 +51,7 @@ def group_query(group)
 
       it "returns one of user1's groups" do
         project = create(:project, namespace: group2, path: 'Foo')
+        issue = create(:issue, project: create(:project, group: group1))
         create(:project_group_link, project: project, group: group1)
 
         post_graphql(group_query(group1), current_user: user1)
@@ -67,6 +68,8 @@ def group_query(group)
         expect(graphql_data['group']['fullName']).to eq(group1.full_name)
         expect(graphql_data['group']['fullPath']).to eq(group1.full_path)
         expect(graphql_data['group']['parentId']).to eq(group1.parent_id)
+        expect(graphql_data['group']['issues']['nodes'].count).to eq(1)
+        expect(graphql_data['group']['issues']['nodes'][0]['iid']).to eq(issue.iid.to_s)
       end
 
       it "does not return a non existing group" do