diff --git a/app/services/lfs/base_file_lock_service.rb b/app/services/lfs/base_file_lock_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c1eeefba7a260275d37dc2138248f2dfe1d39deb
--- /dev/null
+++ b/app/services/lfs/base_file_lock_service.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module Lfs # rubocop:disable Gitlab/BoundedContexts -- These classes already exist so need some work before possible to move
+  class BaseFileLockService < BaseService
+  end
+end
+
+Lfs::BaseFileLockService.prepend_mod
diff --git a/app/services/lfs/lock_file_service.rb b/app/services/lfs/lock_file_service.rb
index b4505e2e49d8866b53360e5b8bc5d0b9115e52a4..684c1e8d963268c660c80772452c0dbc785252df 100644
--- a/app/services/lfs/lock_file_service.rb
+++ b/app/services/lfs/lock_file_service.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module Lfs
-  class LockFileService < BaseService
+  class LockFileService < BaseFileLockService
     def execute
       unless can?(current_user, :push_code, project)
         raise Gitlab::GitAccess::ForbiddenError, 'You have no permissions'
diff --git a/app/services/lfs/unlock_file_service.rb b/app/services/lfs/unlock_file_service.rb
index 677bbacd9fbaeafc9b4593b9b68003828874e8a4..f31118ded623644309e97f7717a74e242636b321 100644
--- a/app/services/lfs/unlock_file_service.rb
+++ b/app/services/lfs/unlock_file_service.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module Lfs
-  class UnlockFileService < BaseService
+  class UnlockFileService < BaseFileLockService
     def execute
       unless can?(current_user, :push_code, project)
         raise Gitlab::GitAccess::ForbiddenError, _('You have no permissions')
diff --git a/ee/app/controllers/projects/path_locks_controller.rb b/ee/app/controllers/projects/path_locks_controller.rb
index 1873b5e7d4e24e7381677bbf496e73fb7d8260ed..591fae56e67a27ae835fb09c6dfdf9528cb802fc 100644
--- a/ee/app/controllers/projects/path_locks_controller.rb
+++ b/ee/app/controllers/projects/path_locks_controller.rb
@@ -59,24 +59,11 @@ def check_license
     end
 
     def lock_file
-      path_lock = PathLocks::LockService.new(project, current_user).execute(path)
-
-      if path_lock.persisted? && sync_with_lfs?
-        Lfs::LockFileService.new(
-          project,
-          current_user,
-          path: path,
-          create_path_lock: false
-        ).execute
-      end
+      PathLocks::LockService.new(project, current_user).execute(path)
     end
 
     def unlock_file(path_lock)
       PathLocks::UnlockService.new(project, current_user).execute(path_lock)
-
-      if sync_with_lfs?
-        Lfs::UnlockFileService.new(project, current_user, path: path_lock.path, force: true).execute
-      end
     end
 
     def lfs_file?
diff --git a/ee/app/graphql/mutations/projects/set_locked.rb b/ee/app/graphql/mutations/projects/set_locked.rb
index 764421d1a962986986d86ae9749a07f1bbd4e354..812ea63b9c5cf6832ea4c04e5a8e6bc8425ab84f 100644
--- a/ee/app/graphql/mutations/projects/set_locked.rb
+++ b/ee/app/graphql/mutations/projects/set_locked.rb
@@ -62,11 +62,7 @@ def fetch_path_lock(file_path)
       def lock_path(file_path)
         return if fetch_path_lock(file_path)
 
-        path_lock = PathLocks::LockService.new(project, current_user).execute(file_path)
-
-        if path_lock.persisted? && sync_with_lfs?(file_path)
-          Lfs::LockFileService.new(project, current_user, path: file_path, create_path_lock: false).execute
-        end
+        PathLocks::LockService.new(project, current_user).execute(file_path)
       end
 
       def unlock_path(file_path)
@@ -75,10 +71,6 @@ def unlock_path(file_path)
         return unless path_lock
 
         PathLocks::UnlockService.new(project, current_user).execute(path_lock)
-
-        if sync_with_lfs?(file_path)
-          Lfs::UnlockFileService.new(project, current_user, path: file_path, force: true).execute
-        end
       end
 
       def sync_with_lfs?(file_path)
diff --git a/ee/app/services/ee/lfs/base_file_lock_service.rb b/ee/app/services/ee/lfs/base_file_lock_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ad7049b577b03a3137981ae2fa419bd3f26c0ce1
--- /dev/null
+++ b/ee/app/services/ee/lfs/base_file_lock_service.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module EE
+  module Lfs # rubocop:disable Gitlab/BoundedContexts -- These classes already exist so need some work before possible to move
+    module BaseFileLockService
+      def initialize(project, user = nil, params = {})
+        # When `syncing_path_lock` is `true` it means that the user locked a
+        # file and the system is now syncing the lock from GitLab's path lock
+        # feature to Git LFS file locking feature.
+        #
+        # This only happens when the file that the user locked is an LFS file.
+        @syncing_path_lock = params[:syncing_path_lock] == true
+        super
+      end
+
+      private
+
+      attr_reader :syncing_path_lock
+
+      def sync_with_file?(lfs_lock_status)
+        lfs_lock_status == :success && !syncing_path_lock && project.licensed_feature_available?(:file_locks)
+      end
+    end
+  end
+end
diff --git a/ee/app/services/ee/lfs/lock_file_service.rb b/ee/app/services/ee/lfs/lock_file_service.rb
index 018bf46de221886acdd231716cf96e70b0f4bb99..1bd5ef93391b1befbd2338aa0e9ed1440be260cb 100644
--- a/ee/app/services/ee/lfs/lock_file_service.rb
+++ b/ee/app/services/ee/lfs/lock_file_service.rb
@@ -6,21 +6,15 @@ module LockFileService
       def execute
         result = super
 
-        create_path_lock(result[:lock].path) if create_path_lock?(result[:status])
+        create_path_lock(result[:lock].path) if sync_with_file?(result[:status])
 
         result
       end
 
       private
 
-      def create_path_lock?(lfs_lock_status)
-        lfs_lock_status == :success &&
-          params[:create_path_lock] != false &&
-          project.feature_available?(:file_locks)
-      end
-
       def create_path_lock(path)
-        PathLocks::LockService.new(project, current_user).execute(path)
+        PathLocks::LockService.new(project, current_user, syncing_lfs_lock: true).execute(path)
       end
     end
   end
diff --git a/ee/app/services/ee/lfs/unlock_file_service.rb b/ee/app/services/ee/lfs/unlock_file_service.rb
index c33877a9129e785527683860cc154dba89fdd01e..1e1f4ba1bdda2a278678f8edcfbcf375c5e34e1b 100644
--- a/ee/app/services/ee/lfs/unlock_file_service.rb
+++ b/ee/app/services/ee/lfs/unlock_file_service.rb
@@ -6,25 +6,19 @@ module UnlockFileService
       def execute
         result = super
 
-        destroy_path_lock(result[:lock].path) if destroy_path_lock?(result[:status])
+        destroy_path_lock(result[:lock].path) if sync_with_file?(result[:status])
 
         result
       end
 
       private
 
-      def destroy_path_lock?(lfs_lock_status)
-        lfs_lock_status == :success &&
-          params[:destroy_path_lock] != false &&
-          project.feature_available?(:file_locks)
-      end
-
       def destroy_path_lock(path)
         path_lock = project.path_locks.for_path(path)
 
         return unless path_lock
 
-        PathLocks::UnlockService.new(project, current_user).execute(path_lock)
+        PathLocks::UnlockService.new(project, current_user, syncing_lfs_lock: true).execute(path_lock)
       end
     end
   end
diff --git a/ee/app/services/path_locks/base_service.rb b/ee/app/services/path_locks/base_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..87f4096b77977182ba3118eb21e264fb0426c4c5
--- /dev/null
+++ b/ee/app/services/path_locks/base_service.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module PathLocks # rubocop:disable Gitlab/BoundedContexts -- These classes already exist so need some work before possible to move
+  class BaseService < BaseService
+    def initialize(project, user = nil, params = {})
+      # When `syncing_lfs_lock` is `true` it means that the user locked a Git
+      # LFS file and the system is now syncing the lock from Git LFS file
+      # locking feature to GitLab's path lock feature.
+      @syncing_lfs_lock = params[:syncing_lfs_lock] == true
+      super
+    end
+
+    private
+
+    attr_reader :syncing_lfs_lock
+
+    def sync_with_lfs?(path)
+      !syncing_lfs_lock && project.lfs_enabled? && lfs_file?(path)
+    end
+
+    def lfs_file?(path)
+      blob = repository.blob_at_branch(repository.root_ref, path)
+
+      return false unless blob
+
+      lfs_blob_ids = LfsPointersFinder.new(repository, path).execute
+
+      lfs_blob_ids.include?(blob.id)
+    end
+  end
+end
diff --git a/ee/app/services/path_locks/lock_service.rb b/ee/app/services/path_locks/lock_service.rb
index c78efbfae814f2a867dab461de3465b7278738f7..4d8fa3794efc4cf175f8f59dd0c369a47eb45a19 100644
--- a/ee/app/services/path_locks/lock_service.rb
+++ b/ee/app/services/path_locks/lock_service.rb
@@ -4,14 +4,18 @@ module PathLocks
   class LockService < BaseService
     AccessDenied = Class.new(StandardError)
 
-    include PathLocksHelper
-
     def execute(path)
       raise AccessDenied, 'You have no permissions' unless can?(current_user, :push_code, project)
 
-      project.path_locks.create(path: path, user: current_user).tap do |path_lock|
-        project.refresh_path_locks_changed_epoch if path_lock.persisted?
-      end
+      path_lock = project.path_locks.create(path: path, user: current_user)
+
+      return unless path_lock.persisted?
+
+      project.refresh_path_locks_changed_epoch
+
+      return unless sync_with_lfs?(path)
+
+      Lfs::LockFileService.new(project, current_user, path: path, syncing_path_lock: true).execute
     end
   end
 end
diff --git a/ee/app/services/path_locks/unlock_service.rb b/ee/app/services/path_locks/unlock_service.rb
index a26a9b9d8383f791c116b52c1de80bc08d70e5ef..fd9a23aee53bd7847a3c2e6b7a4edaac7ccb017a 100644
--- a/ee/app/services/path_locks/unlock_service.rb
+++ b/ee/app/services/path_locks/unlock_service.rb
@@ -4,14 +4,21 @@ module PathLocks
   class UnlockService < BaseService
     AccessDenied = Class.new(StandardError)
 
-    include PathLocksHelper
-
     def execute(path_lock)
-      raise AccessDenied, _('You have no permissions') unless can_unlock?(path_lock)
+      return unless path_lock
+
+      raise AccessDenied, _('You have no permissions') unless can?(current_user, :admin_path_locks, path_lock)
+
+      path = path_lock.path
+      path_lock.destroy
+
+      return unless path_lock.destroyed?
+
+      project.refresh_path_locks_changed_epoch
+
+      return unless sync_with_lfs?(path)
 
-      path_lock.destroy.tap do |record|
-        project.refresh_path_locks_changed_epoch if record.destroyed?
-      end
+      Lfs::UnlockFileService.new(project, current_user, path: path, force: true, syncing_path_lock: true).execute
     end
   end
 end
diff --git a/ee/spec/services/lfs/lock_file_service_spec.rb b/ee/spec/services/lfs/lock_file_service_spec.rb
index d7c9081441274ad426a971c77b81534303b099f2..5f4ef8e3f5d609bf7802582685dc0706e523ce06 100644
--- a/ee/spec/services/lfs/lock_file_service_spec.rb
+++ b/ee/spec/services/lfs/lock_file_service_spec.rb
@@ -5,8 +5,6 @@
 RSpec.describe Lfs::LockFileService, feature_category: :source_code_management do
   let(:project)      { create(:project) }
   let(:current_user) { create(:user) }
-  let(:create_path_lock) { true }
-  let(:params) { { path: 'README.md', create_path_lock: create_path_lock } }
 
   subject { described_class.new(project, current_user, params) }
 
@@ -16,41 +14,50 @@
         project.add_developer(current_user)
       end
 
-      context 'when File Locking is available' do
-        before do
-          stub_licensed_features(file_locks: true)
-        end
+      describe 'File Locking integration' do
+        let(:syncing_path_lock) { false }
+        let(:params) { { path: 'README.md', syncing_path_lock: syncing_path_lock } }
+        let(:file_locks_license) { true }
+        let(:path_lock_service) { PathLocks::LockService }
 
-        it 'creates the Path Lock' do
-          expect { subject.execute }.to change { PathLock.count }.to(1)
+        before do
+          stub_licensed_features(file_locks: file_locks_license)
+          allow(path_lock_service).to receive(:new).and_call_original
         end
 
-        context 'when the lfs file was not locked successfully' do
-          before do
-            allow(subject).to receive(:create_lock!).and_return({ status: :error })
+        context 'when File Locking is available' do
+          it 'creates the Path Lock', :aggregate_failures do
+            expect { subject.execute }.to change { PathLock.count }.to(1)
+            expect(path_lock_service)
+              .to have_received(:new)
+              .with(project, current_user, syncing_lfs_lock: true)
           end
 
-          it 'does not create a Path Lock' do
-            expect { subject.execute }.not_to change { PathLock.count }
+          context 'when the lfs file was not locked successfully' do
+            before do
+              allow(subject).to receive(:create_lock!).and_return({ status: :error })
+            end
+
+            it 'does not create a Path Lock' do
+              expect { subject.execute }.not_to change { PathLock.count }
+            end
           end
-        end
 
-        context 'when create_path_lock is false' do
-          let(:create_path_lock) { false }
+          context 'when syncing_path_lock is true' do
+            let(:syncing_path_lock) { true }
 
-          it 'does not create a Path Lock' do
-            expect { subject.execute }.not_to change { PathLock.count }
+            it 'does not create a Path Lock' do
+              expect { subject.execute }.not_to change { PathLock.count }
+            end
           end
         end
-      end
 
-      context 'when File Locking is not available' do
-        before do
-          stub_licensed_features(file_locks: false)
-        end
+        context 'when File Locking is not available' do
+          let(:file_locks_license) { false }
 
-        it 'does not create the Path Lock' do
-          expect { subject.execute }.not_to change { PathLock.count }
+          it 'does not create the Path Lock' do
+            expect { subject.execute }.not_to change { PathLock.count }
+          end
         end
       end
     end
diff --git a/ee/spec/services/lfs/unlock_file_service_spec.rb b/ee/spec/services/lfs/unlock_file_service_spec.rb
index a2f086b3edb3d30b4521e6a812bdaadc4af2cce7..4130bdd3ea9a408114d19f10772a9849026edc2f 100644
--- a/ee/spec/services/lfs/unlock_file_service_spec.rb
+++ b/ee/spec/services/lfs/unlock_file_service_spec.rb
@@ -12,25 +12,28 @@
   describe '#execute' do
     context 'when authorized' do
       before do
-        project.add_developer(current_user)
+        project.add_developer(lock_author)
       end
 
-      describe 'File Locking integraction' do
-        let(:destroy_path_lock) { true }
-        let(:params) { { id: lock.id, destroy_path_lock: destroy_path_lock } }
+      describe 'File Locking integration' do
+        let(:syncing_path_lock) { false }
+        let(:params) { { id: lock.id, syncing_path_lock: syncing_path_lock } }
         let(:current_user) { lock_author }
         let(:file_locks_license) { true }
+        let(:path_lock_service) { PathLocks::UnlockService }
 
         before do
           stub_licensed_features(file_locks: file_locks_license)
-
-          project.add_developer(lock_author)
           project.path_locks.create!(path: lock.path, user: lock_author)
+          allow(path_lock_service).to receive(:new).and_call_original
         end
 
         context 'when File Locking is available' do
-          it 'deletes the Path Lock' do
+          it 'deletes the Path Lock', :aggregate_failures do
             expect { subject.execute }.to change { PathLock.count }.to(0)
+            expect(path_lock_service)
+              .to have_received(:new)
+              .with(project, lock_author, syncing_lfs_lock: true)
           end
 
           context 'when the lfs file was not unlocked successfully' do
@@ -43,8 +46,8 @@
             end
           end
 
-          context 'when destroy_path_lock is false' do
-            let(:destroy_path_lock) { false }
+          context 'when syncing_path_lock is true' do
+            let(:syncing_path_lock) { true }
 
             it 'does not delete the Path Lock' do
               expect { subject.execute }.not_to change { PathLock.count }
diff --git a/ee/spec/services/path_locks/lock_service_spec.rb b/ee/spec/services/path_locks/lock_service_spec.rb
index 7fb958858398aec9fff6d4e3fb89fd3e79023cd1..45ee1d7f0561a130a9bcf3613ddf10d5eac42f32 100644
--- a/ee/spec/services/path_locks/lock_service_spec.rb
+++ b/ee/spec/services/path_locks/lock_service_spec.rb
@@ -3,18 +3,20 @@
 require 'spec_helper'
 
 RSpec.describe PathLocks::LockService, feature_category: :source_code_management do
-  let(:current_user) { create(:user) }
-  let(:project)      { create(:project) }
-  let(:path)         { 'app/models' }
+  let_it_be(:project) { create(:project, :repository) }
+  let_it_be(:current_user) { create(:user) }
+
+  let(:syncing_lfs_lock) { false }
+  let(:path) { 'app/models' }
 
   describe '#execute(path)' do
-    subject(:execute) { described_class.new(project, current_user).execute(path) }
+    subject(:execute) do
+      described_class.new(project, current_user, syncing_lfs_lock: syncing_lfs_lock).execute(path)
+    end
 
     context 'when user can push code' do
-      before do
-        allow_next_instance_of(described_class) do |instance|
-          allow(instance).to receive(:can?).with(current_user, :push_code, project).and_return(true)
-        end
+      before_all do
+        project.add_developer(current_user)
       end
 
       it 'locks path' do
@@ -22,6 +24,53 @@
       end
 
       it_behaves_like 'refreshes project.path_locks_changed_epoch value'
+
+      describe 'Lfs File Lock integration' do
+        let(:lfs_enabled) { true }
+        let(:lfs_file_lock_service) { Lfs::LockFileService }
+
+        before do
+          allow(project).to receive(:lfs_enabled?).and_return(lfs_enabled)
+          allow(lfs_file_lock_service).to receive(:new).and_call_original
+        end
+
+        context 'when the file is an lfs file' do
+          let(:path) { 'files/lfs/lfs_object.iso' }
+
+          before do
+            allow(project.repository).to receive(:root_ref).and_return('lfs')
+          end
+
+          it 'creates the Lfs File Lock', :aggregate_failures do
+            expect { execute }.to change { LfsFileLock.count }.from(0).to(1)
+            expect(lfs_file_lock_service)
+              .to have_received(:new)
+              .with(project, current_user, syncing_path_lock: true, path: path)
+          end
+
+          context 'when lfs is disabled' do
+            let(:lfs_enabled) { false }
+
+            it 'does not create an LfsFileLock' do
+              expect { execute }.not_to change { LfsFileLock.count }
+            end
+          end
+
+          context 'when syncing_lfs_lock is true' do
+            let(:syncing_lfs_lock) { true }
+
+            it 'does not create an LfsFileLock' do
+              expect { execute }.not_to change { LfsFileLock.count }
+            end
+          end
+        end
+
+        context 'when the file is not an lfs file' do
+          it 'does not create an LfsFileLock' do
+            expect { execute }.not_to change { LfsFileLock.count }
+          end
+        end
+      end
     end
 
     context 'when user cannot push code' do
diff --git a/ee/spec/services/path_locks/unlock_service_spec.rb b/ee/spec/services/path_locks/unlock_service_spec.rb
index 98635fce46af69995a5c3ee66c64a3a3e875f767..6c315f6f520bca8d0317331f4a4278c14fb54411 100644
--- a/ee/spec/services/path_locks/unlock_service_spec.rb
+++ b/ee/spec/services/path_locks/unlock_service_spec.rb
@@ -3,19 +3,21 @@
 require 'spec_helper'
 
 RSpec.describe PathLocks::UnlockService, feature_category: :source_code_management do
-  let(:path_lock)    { create :path_lock }
-  let(:current_user) { path_lock.user }
-  let(:project)      { path_lock.project }
-  let(:path)         { path_lock.path }
+  let_it_be(:project) { create(:project, :repository) }
+  let_it_be(:current_user) { create(:user) }
+
+  let(:path) { 'app/models' }
+  let!(:path_lock) { create(:path_lock, path: path, user: current_user, project: project) }
+  let(:syncing_lfs_lock) { false }
 
   describe '#execute(path_lock)' do
-    subject(:execute) { described_class.new(project, current_user).execute(path_lock) }
+    subject(:execute) do
+      described_class.new(project, current_user, syncing_lfs_lock: syncing_lfs_lock).execute(path_lock)
+    end
 
-    context 'when the user can unlock the path lock' do
-      before do
-        allow_next_instance_of(described_class) do |instance|
-          allow(instance).to receive(:can?).with(current_user, :admin_path_locks, path_lock).and_return(true)
-        end
+    context 'when the user can admin_path_locks' do
+      before_all do
+        project.add_developer(current_user)
       end
 
       it 'unlocks path' do
@@ -23,6 +25,54 @@
       end
 
       it_behaves_like 'refreshes project.path_locks_changed_epoch value'
+
+      describe 'Lfs File Lock integration' do
+        let(:lfs_enabled) { true }
+        let(:lfs_file_lock_service) { Lfs::UnlockFileService }
+
+        before do
+          allow(project).to receive(:lfs_enabled?).and_return(lfs_enabled)
+          allow(lfs_file_lock_service).to receive(:new).and_call_original
+          project.lfs_file_locks.create!(path: path, user: current_user)
+        end
+
+        context 'when the file is an lfs file' do
+          let(:path) { 'files/lfs/lfs_object.iso' }
+
+          before do
+            allow(project.repository).to receive(:root_ref).and_return('lfs')
+          end
+
+          it 'destroys the Lfs File Lock', :aggregate_failures do
+            expect { execute }.to change { LfsFileLock.count }.from(1).to(0)
+            expect(lfs_file_lock_service)
+              .to have_received(:new)
+              .with(project, current_user, force: true, syncing_path_lock: true, path: path)
+          end
+
+          context 'when lfs is disabled' do
+            let(:lfs_enabled) { false }
+
+            it 'does not destroy the LfsFileLock' do
+              expect { execute }.not_to change { LfsFileLock.count }
+            end
+          end
+
+          context 'when syncing_lfs_lock is true' do
+            let(:syncing_lfs_lock) { true }
+
+            it 'does not destroy the LfsFileLock' do
+              expect { execute }.not_to change { LfsFileLock.count }
+            end
+          end
+        end
+
+        context 'when the file is not an lfs file' do
+          it 'does not destroy the LfsFileLock' do
+            expect { execute }.not_to change { LfsFileLock.count }
+          end
+        end
+      end
     end
 
     context 'when the user cannot unlock the path lock' do