diff --git a/app/finders/projects/members/effective_access_level_finder.rb b/app/finders/projects/members/effective_access_level_finder.rb
index 4538fc4c8554e7a07a4d1c50bf9d3bf289bd2dd6..d17609ff59ff65f20b388778a6bcb600f6fe7efc 100644
--- a/app/finders/projects/members/effective_access_level_finder.rb
+++ b/app/finders/projects/members/effective_access_level_finder.rb
@@ -40,7 +40,7 @@ def all_possible_avenues_of_membership
         avenues = [authorizable_project_members]
 
         avenues << if project.personal?
-                     project_owner_acting_as_maintainer
+                     project_owner
                    else
                      authorizable_group_members
                    end
@@ -85,9 +85,15 @@ def members_from_project_group_shares
         Member.from_union(members)
       end
 
-      def project_owner_acting_as_maintainer
+      # workaround until we migrate Project#owners to have membership with
+      # OWNER access level
+      def project_owner
         user_id = project.namespace.owner.id
-        access_level = Gitlab::Access::MAINTAINER
+        access_level = if ::Feature.enabled?(:personal_project_owner_with_owner_access, default_enabled: :yaml)
+                         Gitlab::Access::OWNER
+                       else
+                         Gitlab::Access::MAINTAINER
+                       end
 
         Member
           .from(generate_from_statement([[user_id, access_level]])) # rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/models/concerns/select_for_project_authorization.rb b/app/models/concerns/select_for_project_authorization.rb
index 49342e30db62c0d6554a8f373bb930bbaa9a2a88..e176e29f9d9163eac7545d13a32fc706cef4ed84 100644
--- a/app/models/concerns/select_for_project_authorization.rb
+++ b/app/models/concerns/select_for_project_authorization.rb
@@ -8,8 +8,14 @@ def select_for_project_authorization
       select("projects.id AS project_id", "members.access_level")
     end
 
-    def select_as_maintainer_for_project_authorization
-      select(["projects.id AS project_id", "#{Gitlab::Access::MAINTAINER} AS access_level"])
+    # workaround until we migrate Project#owners to have membership with
+    # OWNER access level
+    def select_project_owner_for_project_authorization
+      if ::Feature.enabled?(:personal_project_owner_with_owner_access, default_enabled: :yaml)
+        select(["projects.id AS project_id", "#{Gitlab::Access::OWNER} AS access_level"])
+      else
+        select(["projects.id AS project_id", "#{Gitlab::Access::MAINTAINER} AS access_level"])
+      end
     end
   end
 end
diff --git a/app/models/project.rb b/app/models/project.rb
index e86d704f3b6e04f606d3bb7e5911d855bd8cf88b..fec362b6bf1247cd14a395435d479301af36e032 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -445,7 +445,7 @@ def self.integration_association_name(name)
   delegate :name, to: :owner, allow_nil: true, prefix: true
   delegate :members, to: :team, prefix: true
   delegate :add_user, :add_users, to: :team
-  delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_role, to: :team
+  delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_owner, :add_role, to: :team
   delegate :group_runners_enabled, :group_runners_enabled=, to: :ci_cd_settings, allow_nil: true
   delegate :root_ancestor, to: :namespace, allow_nil: true
   delegate :last_pipeline, to: :commit, allow_nil: true
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index c3c7508df9f391462dcc96c174e4111e2e666e12..ee5ecc2dd3c614b44921ccea38735520860d77d5 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -23,6 +23,10 @@ def add_maintainer(user, current_user: nil)
     add_user(user, :maintainer, current_user: current_user)
   end
 
+  def add_owner(user, current_user: nil)
+    add_user(user, :owner, current_user: current_user)
+  end
+
   def add_role(user, role, current_user: nil)
     public_send(:"add_#{role}", user, current_user: current_user) # rubocop:disable GitlabSecurity/PublicSend
   end
@@ -103,7 +107,9 @@ def owners
       if group
         group.owners
       else
-        [project.owner]
+        # workaround until we migrate Project#owners to have membership with
+        # OWNER access level
+        Array.wrap(fetch_members(Gitlab::Access::OWNER)) | Array.wrap(project.owner)
       end
   end
 
diff --git a/app/services/members/projects/creator_service.rb b/app/services/members/projects/creator_service.rb
index 2e97417707523700f701861f2458372025f7337e..4dba81acf73acd13fa5d1320626975c17b5c9a7e 100644
--- a/app/services/members/projects/creator_service.rb
+++ b/app/services/members/projects/creator_service.rb
@@ -4,7 +4,7 @@ module Members
   module Projects
     class CreatorService < Members::CreatorService
       def self.access_levels
-        Gitlab::Access.sym_options
+        Gitlab::Access.sym_options_with_owner
       end
 
       private
diff --git a/app/services/notification_recipients/builder/project_maintainers.rb b/app/services/notification_recipients/builder/project_maintainers.rb
index e8f22c00a833b2765432cdca2cc948f9026da7e0..a295929a1a9608acc5b9c8a2f268e76269bb0dba 100644
--- a/app/services/notification_recipients/builder/project_maintainers.rb
+++ b/app/services/notification_recipients/builder/project_maintainers.rb
@@ -14,6 +14,7 @@ def build!
         return [] unless project
 
         add_recipients(project.team.maintainers, :mention, nil)
+        add_recipients(project.team.owners, :mention, nil)
       end
 
       def acting_user
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index c885369dfecf202c995d109e2401b57c5f671e8a..ecae90e576decb27fae45efc7e76d71f0b72eddd 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -147,7 +147,11 @@ def setup_authorizations
           priority: UserProjectAccessChangedService::LOW_PRIORITY
         )
       else
-        @project.add_maintainer(@project.namespace.owner, current_user: current_user)
+        if ::Feature.enabled?(:personal_project_owner_with_owner_access, default_enabled: :yaml)
+          @project.add_owner(@project.namespace.owner, current_user: current_user)
+        else
+          @project.add_maintainer(@project.namespace.owner, current_user: current_user)
+        end
       end
     end
 
diff --git a/config/feature_flags/development/personal_project_owner_with_owner_access.yml b/config/feature_flags/development/personal_project_owner_with_owner_access.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a82521e88e531837e3098cdd83717842a81521d2
--- /dev/null
+++ b/config/feature_flags/development/personal_project_owner_with_owner_access.yml
@@ -0,0 +1,8 @@
+---
+name: personal_project_owner_with_owner_access
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78193
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351919
+milestone: '14.8'
+type: development
+group: group::workspace
+default_enabled: false
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index a00ac13c87bdc08c6a6701003d2bd051678ed896..36c81f8ca9b323b43abb1f3852e0c0054bfd7b8e 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -33,14 +33,27 @@ usernames. A GitLab administrator can configure the GitLab instance to
 
 ## Project members permissions
 
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/219299) in GitLab 14.8, personal namespace owners appear with Owner role in new projects in their namespace. Introduced [with a flag](../administration/feature_flags.md) named `personal_project_owner_with_owner_access`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, personal namespace owners appearing with the Owner role in new projects in their namespace is disabled. To make it available,
+ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `personal_project_owner_with_owner_access`.
+The feature is not ready for production use.
+On GitLab.com, this feature is not available.
+
 A user's role determines what permissions they have on a project. The Owner role provides all permissions but is
 available only:
 
 - For group owners. The role is inherited for a group's projects.
 - For Administrators.
 
-Personal namespace owners have the same permissions as an Owner, but are displayed with the Maintainer role on projects created in their personal namespace.
-For more information, see [projects members documentation](project/members/index.md).
+Personal [namespace](group/index.md#namespaces) owners:
+
+- Are displayed as having the Maintainer role on projects in the namespace, but have the same permissions as a user with the Owner role.
+- (Disabled by default) In GitLab 14.8 and later, for new projects in the namespace, are displayed as having the Owner role.
+
+For more information about how to manage project members, see
+[members of a project](project/members/index.md).
 
 The following table lists project permissions available for each role:
 
diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb
index 3e09d488bc34cc957cf2825d67d64a6b497c8c02..d0b426aeb60c7106a6bd0cbb94b5ffab1d2b3355 100644
--- a/lib/gitlab/access.rb
+++ b/lib/gitlab/access.rb
@@ -33,7 +33,13 @@ module Access
     MAINTAINER_SUBGROUP_ACCESS = 1
 
     class << self
-      delegate :values, to: :options
+      def values
+        if ::Feature.enabled?(:personal_project_owner_with_owner_access, default_enabled: :yaml)
+          options_with_owner.values
+        else
+          options.values
+        end
+      end
 
       def all_values
         options_with_owner.values
diff --git a/lib/gitlab/project_authorizations.rb b/lib/gitlab/project_authorizations.rb
index 121626ced564b7ecf0516891635afc39319a8f63..1d7b179baf05be15fe6da97bdacacf32c5f773b9 100644
--- a/lib/gitlab/project_authorizations.rb
+++ b/lib/gitlab/project_authorizations.rb
@@ -22,7 +22,7 @@ def calculate
         user.projects_with_active_memberships.select_for_project_authorization,
 
         # The personal projects of the user.
-        user.personal_projects.select_as_maintainer_for_project_authorization,
+        user.personal_projects.select_project_owner_for_project_authorization,
 
         # Projects that belong directly to any of the groups the user has
         # access to.
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index d8ef95cf11a46ba6f4a305c35aa0cee99ce10554..d6af5976743675cf5a935f15c3dcec94c724bd0c 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -665,7 +665,7 @@
         sign_in(user)
       end
 
-      it 'does not create a member' do
+      it 'creates a member' do
         expect do
           post :create, params: {
                           user_ids: stranger.id,
@@ -673,7 +673,9 @@
                           access_level: Member::OWNER,
                           project_id: project
                         }
-        end.to change { project.members.count }.by(0)
+        end.to change { project.members.count }.by(1)
+
+        expect(project.team_members).to include(user)
       end
     end
 
diff --git a/spec/finders/projects/members/effective_access_level_finder_spec.rb b/spec/finders/projects/members/effective_access_level_finder_spec.rb
index 33fbb5aca3045f5403953e7c3dd2b03111233ebf..446b0f8f9a23c2676f2ea19603a99d68a3264da0 100644
--- a/spec/finders/projects/members/effective_access_level_finder_spec.rb
+++ b/spec/finders/projects/members/effective_access_level_finder_spec.rb
@@ -11,21 +11,40 @@
   context 'for a personal project' do
     let_it_be(:project) { create(:project) }
 
-    shared_examples_for 'includes access level of the owner of the project as Maintainer' do
-      it 'includes access level of the owner of the project as Maintainer' do
-        expect(subject).to(
-          contain_exactly(
-            hash_including(
-              'user_id' => project.namespace.owner.id,
-              'access_level' => Gitlab::Access::MAINTAINER
+    shared_examples_for 'includes access level of the owner of the project' do
+      context 'when personal_project_owner_with_owner_access feature flag is enabled' do
+        it 'includes access level of the owner of the project as Owner' do
+          expect(subject).to(
+            contain_exactly(
+              hash_including(
+                'user_id' => project.namespace.owner.id,
+                'access_level' => Gitlab::Access::OWNER
+              )
             )
           )
-        )
+        end
+      end
+
+      context 'when personal_project_owner_with_owner_access feature flag is disabled' do
+        before do
+          stub_feature_flags(personal_project_owner_with_owner_access: false)
+        end
+
+        it 'includes access level of the owner of the project as Maintainer' do
+          expect(subject).to(
+            contain_exactly(
+              hash_including(
+                'user_id' => project.namespace.owner.id,
+                'access_level' => Gitlab::Access::MAINTAINER
+              )
+            )
+          )
+        end
       end
     end
 
     context 'when the project owner is a member of the project' do
-      it_behaves_like 'includes access level of the owner of the project as Maintainer'
+      it_behaves_like 'includes access level of the owner of the project'
     end
 
     context 'when the project owner is not explicitly a member of the project' do
@@ -33,7 +52,7 @@
         project.members.find_by(user_id: project.namespace.owner.id).destroy!
       end
 
-      it_behaves_like 'includes access level of the owner of the project as Maintainer'
+      it_behaves_like 'includes access level of the owner of the project'
     end
   end
 
@@ -84,17 +103,32 @@
 
   context 'for a project within a group' do
     context 'project in a root group' do
-      it 'includes access levels of users who are direct members of the parent group' do
-        group_member = create(:group_member, :developer, source: group)
+      context 'includes access levels of users who are direct members of the parent group' do
+        it 'when access level is developer' do
+          group_member = create(:group_member, :developer, source: group)
 
-        expect(subject).to(
-          include(
-            hash_including(
-              'user_id' => group_member.user.id,
-              'access_level' => Gitlab::Access::DEVELOPER
+          expect(subject).to(
+            include(
+              hash_including(
+                'user_id' => group_member.user.id,
+                'access_level' => Gitlab::Access::DEVELOPER
+              )
             )
           )
-        )
+        end
+
+        it 'when access level is owner' do
+          group_member = create(:group_member, :owner, source: group)
+
+          expect(subject).to(
+            include(
+              hash_including(
+                'user_id' => group_member.user.id,
+                'access_level' => Gitlab::Access::OWNER
+              )
+            )
+          )
+        end
       end
     end
 
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index 7852470196b02da429389911a59ef48ba88ebe87..8630762e06f886bb4c6f42e0f40df92566904a93 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -34,12 +34,28 @@ def map_access_levels(rows)
         .to include(owned_project.id, other_project.id, group_project.id)
     end
 
-    it 'includes the correct access levels' do
-      mapping = map_access_levels(authorizations)
+    context 'when personal_project_owner_with_owner_access feature flag is enabled' do
+      it 'includes the correct access levels' do
+        mapping = map_access_levels(authorizations)
+
+        expect(mapping[owned_project.id]).to eq(Gitlab::Access::OWNER)
+        expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
+        expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
+      end
+    end
 
-      expect(mapping[owned_project.id]).to eq(Gitlab::Access::MAINTAINER)
-      expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
-      expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
+    context 'when personal_project_owner_with_owner_access feature flag is disabled' do
+      before do
+        stub_feature_flags(personal_project_owner_with_owner_access: false)
+      end
+
+      it 'includes the correct access levels' do
+        mapping = map_access_levels(authorizations)
+
+        expect(mapping[owned_project.id]).to eq(Gitlab::Access::MAINTAINER)
+        expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
+        expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
+      end
     end
   end
 
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index bfdebbc33df002741cee95a5a2f191837c343e46..5b11f9d828a675bca87853a28ae63ec93bf083c3 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -225,7 +225,7 @@
     let_it_be(:maintainer) { create(:user) }
     let_it_be(:developer) { create(:user) }
     let_it_be(:guest) { create(:user) }
-    let_it_be(:project) { create(:project, namespace: maintainer.namespace) }
+    let_it_be(:project) { create(:project, group: create(:group)) }
     let_it_be(:access_levels) { [Gitlab::Access::DEVELOPER, Gitlab::Access::MAINTAINER] }
 
     subject(:members_with_access_levels) { project.team.members_with_access_levels(access_levels) }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 58f58232d52f3f2d33638a8e9160d98ad3dd173c..4aee36bf05c58d3c304f717200f90ae90d5dc87f 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -3717,7 +3717,7 @@
 
     context 'with min_access_level' do
       let!(:user) { create(:user) }
-      let!(:project) { create(:project, :private, namespace: user.namespace) }
+      let!(:project) { create(:project, :private, group: create(:group)) }
 
       before do
         project.add_developer(user)
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index 02061bb8ab6dbceaa191de7e900b1ab647dc143d..bb8d3ad9a6dee8d9bd33b834e3c7e9218c38edca 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -673,13 +673,30 @@
     end
 
     context 'adding owner to project' do
-      it 'returns 403' do
-        expect do
-          post api("/projects/#{project.id}/members", maintainer),
-               params: { user_id: stranger.id, access_level: Member::OWNER }
+      context 'when personal_project_owner_with_owner_access feature flag is enabled' do
+        it 'returns created status' do
+          expect do
+            post api("/projects/#{project.id}/members", maintainer),
+                 params: { user_id: stranger.id, access_level: Member::OWNER }
 
-          expect(response).to have_gitlab_http_status(:bad_request)
-        end.not_to change { project.members.count }
+            expect(response).to have_gitlab_http_status(:created)
+          end.to change { project.members.count }.by(1)
+        end
+      end
+
+      context 'when personal_project_owner_with_owner_access feature flag is disabled' do
+        before do
+          stub_feature_flags(personal_project_owner_with_owner_access: false)
+        end
+
+        it 'returns created status' do
+          expect do
+            post api("/projects/#{project.id}/members", maintainer),
+                 params: { user_id: stranger.id, access_level: Member::OWNER }
+
+            expect(response).to have_gitlab_http_status(:bad_request)
+          end.not_to change { project.members.count }
+        end
       end
     end
 
diff --git a/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb b/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb
index c6b184bd0038c5f6812712d08c030be7f5a52536..537d198638438f293bebd81ca9e0b9e59ef09aa3 100644
--- a/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb
+++ b/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb
@@ -40,7 +40,7 @@
         it 'is called' do
           ProjectAuthorization.delete_all
 
-          expect(callback).to receive(:call).with(project.id, Gitlab::Access::MAINTAINER).once
+          expect(callback).to receive(:call).with(project.id, Gitlab::Access::OWNER).once
 
           service.execute
         end
@@ -60,20 +60,20 @@
 
           to_be_removed = [project2.id]
           to_be_added = [
-            { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+            { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
           ]
 
           expect(service.execute).to eq([to_be_removed, to_be_added])
         end
 
         it 'finds duplicate entries that has to be removed' do
-          [Gitlab::Access::MAINTAINER, Gitlab::Access::REPORTER].each do |access_level|
+          [Gitlab::Access::OWNER, Gitlab::Access::REPORTER].each do |access_level|
             user.project_authorizations.create!(project: project, access_level: access_level)
           end
 
           to_be_removed = [project.id]
           to_be_added = [
-            { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+            { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
           ]
 
           expect(service.execute).to eq([to_be_removed, to_be_added])
@@ -85,7 +85,7 @@
 
           to_be_removed = [project.id]
           to_be_added = [
-            { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+            { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
           ]
 
           expect(service.execute).to eq([to_be_removed, to_be_added])
@@ -143,16 +143,16 @@
     end
 
     it 'sets the keys to the project IDs' do
-      expect(hash.keys).to eq([project.id])
+      expect(hash.keys).to match_array([project.id])
     end
 
     it 'sets the values to the access levels' do
-      expect(hash.values).to eq([Gitlab::Access::MAINTAINER])
+      expect(hash.values).to match_array([Gitlab::Access::OWNER])
     end
 
     context 'personal projects' do
       it 'includes the project with the right access level' do
-        expect(hash[project.id]).to eq(Gitlab::Access::MAINTAINER)
+        expect(hash[project.id]).to eq(Gitlab::Access::OWNER)
       end
     end
 
@@ -242,7 +242,7 @@
       value = hash.values[0]
 
       expect(value.project_id).to eq(project.id)
-      expect(value.access_level).to eq(Gitlab::Access::MAINTAINER)
+      expect(value.access_level).to eq(Gitlab::Access::OWNER)
     end
   end
 
@@ -267,7 +267,7 @@
       end
 
       it 'includes the access level for every row' do
-        expect(row.access_level).to eq(Gitlab::Access::MAINTAINER)
+        expect(row.access_level).to eq(Gitlab::Access::OWNER)
       end
     end
   end
@@ -283,7 +283,7 @@
       rows = service.fresh_authorizations.to_a
 
       expect(rows.length).to eq(1)
-      expect(rows.first.access_level).to eq(Gitlab::Access::MAINTAINER)
+      expect(rows.first.access_level).to eq(Gitlab::Access::OWNER)
     end
 
     context 'every returned row' do
@@ -294,7 +294,7 @@
       end
 
       it 'includes the access level' do
-        expect(row.access_level).to eq(Gitlab::Access::MAINTAINER)
+        expect(row.access_level).to eq(Gitlab::Access::OWNER)
       end
     end
   end
diff --git a/spec/services/members/projects/creator_service_spec.rb b/spec/services/members/projects/creator_service_spec.rb
index c6917a21bcd847a0fd53af90bd54c47bb911c4c1..7ba183759bc5c23e3b1604b25a6bae895bcf047c 100644
--- a/spec/services/members/projects/creator_service_spec.rb
+++ b/spec/services/members/projects/creator_service_spec.rb
@@ -9,8 +9,8 @@
   end
 
   describe '.access_levels' do
-    it 'returns Gitlab::Access.sym_options' do
-      expect(described_class.access_levels).to eq(Gitlab::Access.sym_options)
+    it 'returns Gitlab::Access.sym_options_with_owner' do
+      expect(described_class.access_levels).to eq(Gitlab::Access.sym_options_with_owner)
     end
   end
 end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 9cbc16f0c95484b21dfa5fab954258f6d75099c5..d12b70d403ae2042dc79e11a87b8022d10733aea 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -3312,7 +3312,7 @@ def create_pipeline(user, status)
       describe "##{sym}" do
         subject(:notify!) { notification.send(sym, domain) }
 
-        it 'emails current watching maintainers' do
+        it 'emails current watching maintainers and owners' do
           expect(Notify).to receive(:"#{sym}_email").at_least(:once).and_call_original
 
           notify!
@@ -3410,7 +3410,7 @@ def create_pipeline(user, status)
         reset_delivered_emails!
       end
 
-      it 'emails current watching maintainers' do
+      it 'emails current watching maintainers and owners' do
         notification.remote_mirror_update_failed(remote_mirror)
 
         should_only_email(u_maintainer1, u_maintainer2, u_owner)
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index 43a9d69f3bbb35723b0ce5b2f5dc2ecd69e30bd2..41c82ef6a2f06ab866b8f000773675dc4f6fb468 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -116,14 +116,34 @@
   end
 
   context 'user namespace' do
-    it 'creates a project in user namespace' do
-      project = create_project(user, opts)
+    context 'when personal_project_owner_with_owner_access feature flag is enabled' do
+      it 'creates a project in user namespace' do
+        project = create_project(user, opts)
 
-      expect(project).to be_valid
-      expect(project.first_owner).to eq(user)
-      expect(project.team.maintainers).to include(user)
-      expect(project.namespace).to eq(user.namespace)
-      expect(project.project_namespace).to be_in_sync_with_project(project)
+        expect(project).to be_valid
+        expect(project.first_owner).to eq(user)
+        expect(project.team.maintainers).not_to include(user)
+        expect(project.team.owners).to contain_exactly(user)
+        expect(project.namespace).to eq(user.namespace)
+        expect(project.project_namespace).to be_in_sync_with_project(project)
+      end
+    end
+
+    context 'when personal_project_owner_with_owner_access feature flag is disabled' do
+      before do
+        stub_feature_flags(personal_project_owner_with_owner_access: false)
+      end
+
+      it 'creates a project in user namespace' do
+        project = create_project(user, opts)
+
+        expect(project).to be_valid
+        expect(project.first_owner).to eq(user)
+        expect(project.team.maintainers).to contain_exactly(user)
+        expect(project.team.owners).to contain_exactly(user)
+        expect(project.namespace).to eq(user.namespace)
+        expect(project.project_namespace).to be_in_sync_with_project(project)
+      end
     end
   end
 
@@ -162,7 +182,7 @@
         expect(project).to be_persisted
         expect(project.owner).to eq(user)
         expect(project.first_owner).to eq(user)
-        expect(project.team.maintainers).to contain_exactly(user)
+        expect(project.team.owners).to contain_exactly(user)
         expect(project.namespace).to eq(user.namespace)
         expect(project.project_namespace).to be_in_sync_with_project(project)
       end
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index a31902c7f166381c8dd33194409c90f0e27e1b78..b8fd2455445e3a65983ae75c751853e393d769ef 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -52,7 +52,7 @@
         it 'is called' do
           ProjectAuthorization.delete_all
 
-          expect(callback).to receive(:call).with(project.id, Gitlab::Access::MAINTAINER).once
+          expect(callback).to receive(:call).with(project.id, Gitlab::Access::OWNER).once
 
           service.execute
         end
@@ -73,7 +73,7 @@
       to_be_removed = [project_authorization.project_id]
 
       to_be_added = [
-        { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+        { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
       ]
 
       expect(service).to receive(:update_authorizations)
@@ -83,14 +83,14 @@
     end
 
     it 'removes duplicate entries' do
-      [Gitlab::Access::MAINTAINER, Gitlab::Access::REPORTER].each do |access_level|
+      [Gitlab::Access::OWNER, Gitlab::Access::REPORTER].each do |access_level|
         user.project_authorizations.create!(project: project, access_level: access_level)
       end
 
       to_be_removed = [project.id]
 
       to_be_added = [
-        { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+        { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
       ]
       expect(service).to(
         receive(:update_authorizations)
@@ -103,7 +103,7 @@
       project_authorization = ProjectAuthorization.where(
         project_id: project.id,
         user_id: user.id,
-        access_level: Gitlab::Access::MAINTAINER)
+        access_level: Gitlab::Access::OWNER)
       expect(project_authorization).to exist
     end
 
@@ -116,7 +116,7 @@
       to_be_removed = [project_authorization.project_id]
 
       to_be_added = [
-        { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+        { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
       ]
 
       expect(service).to receive(:update_authorizations)