diff --git a/dvc/cli.py b/dvc/cli.py
index 5f406ac36..27dd57050 100644
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -8,6 +8,7 @@ from multiprocessing import cpu_count
 from dvc.logger import Logger
 from dvc.command.init import CmdInit
 from dvc.command.remove import CmdRemove
+from dvc.command.move import CmdMove
 from dvc.command.run import CmdRun
 from dvc.command.repro import CmdRepro
 from dvc.command.data_sync import CmdDataPush, CmdDataPull, CmdDataFetch
@@ -289,6 +290,19 @@ def parse_args(argv=None):
                         help='DVC files.')
     remove_parser.set_defaults(func=CmdRemove)
 
+    # Move
+    move_parser = subparsers.add_parser(
+                        'move',
+                        parents=[parent_parser],
+                        help='Move output of DVC file.')
+    move_parser.add_argument(
+                        'src',
+                        help='Source')
+    move_parser.add_argument(
+                        'dst',
+                        help='Destination')
+    move_parser.set_defaults(func=CmdMove)
+
     # Garbage collector
     gc_parser = subparsers.add_parser(
                         'gc',
diff --git a/dvc/command/move.py b/dvc/command/move.py
new file mode 100644
index 000000000..bef31165b
--- /dev/null
+++ b/dvc/command/move.py
@@ -0,0 +1,13 @@
+from dvc.exceptions import DvcException
+from dvc.command.common.base import CmdBase
+
+
+class CmdMove(CmdBase):
+    def run(self):
+        try:
+            self.project.move(self.args.src, self.args.dst)
+        except DvcException as ex:
+            self.project.logger.error('Failed to move \'{}\' -> \'{}\''.format(self.args.src,
+                                                                               self.args.dst), ex)
+            return 1
+        return 0
diff --git a/dvc/dependency/local.py b/dvc/dependency/local.py
index 0d7532107..47a903929 100644
--- a/dvc/dependency/local.py
+++ b/dvc/dependency/local.py
@@ -33,7 +33,7 @@ class DependencyLOCAL(DependencyBase):
         if not os.path.isabs(path):
             path = self.ospath(path)
             path = os.path.join(stage.cwd, path)
-        self.path = os.path.normpath(path)
+        self.path = os.path.abspath(os.path.normpath(path))
 
         self.path_info = {'scheme': 'local',
                           'path': self.path}
diff --git a/dvc/output/local.py b/dvc/output/local.py
index b482e350e..703dee528 100644
--- a/dvc/output/local.py
+++ b/dvc/output/local.py
@@ -82,3 +82,15 @@ class OutputLOCAL(DependencyLOCAL):
         self.remote.remove(self.path_info)
         if ignore_remove and self.use_cache:
             self.project.scm.ignore_remove(self.path)
+
+    def move(self, out):
+        if self.use_cache:
+            self.project.scm.ignore_remove(self.path)
+
+        self.remote.move(self.path_info, out.path_info)
+        self.path = out.path
+        self.path_info = out.path_info
+        self.save()
+
+        if self.use_cache:
+            self.project.scm.ignore(self.path)
diff --git a/dvc/project.py b/dvc/project.py
index 370306421..582f3e7af 100644
--- a/dvc/project.py
+++ b/dvc/project.py
@@ -5,6 +5,7 @@ import json
 import networkx as nx
 from jsonpath_rw import parse
 
+import dvc.output as Output
 from dvc.logger import Logger
 from dvc.exceptions import DvcException
 from dvc.stage import Stage
@@ -137,6 +138,35 @@ class Project(object):
 
         return stage
 
+    def move(self, from_path, to_path):
+        from_out = Output.loads_from(Stage(self, cwd=os.curdir), [from_path])[0]
+
+        found = False
+        for stage in self.stages():
+            for out in stage.outs:
+                if out.path != from_out.path:
+                    continue
+
+                if not stage.is_data_source:
+                    raise DvcException('Dvcfile \'{}\' is not a data source.'.format(stage.rel_path))
+
+                found = True
+                to_out = Output.loads_from(out.stage, [to_path], out.cache, out.metric)[0]
+                out.move(to_out)
+
+                stage_base = os.path.basename(stage.path).rstrip(Stage.STAGE_FILE_SUFFIX)
+                stage_dir = os.path.dirname(stage.path)
+                from_base = os.path.basename(from_path)
+                to_base = os.path.basename(to_path)
+                if stage_base == from_base:
+                    os.unlink(stage.path)
+                    stage.path = os.path.join(stage_dir, to_base + Stage.STAGE_FILE_SUFFIX)
+
+            stage.dump()
+
+        if not found:
+            raise DvcException('Unable to find dvcfile with output \'{}\''.format(from_path))
+
     def run(self,
             cmd=None,
             deps=[],
diff --git a/dvc/remote/base.py b/dvc/remote/base.py
index 11e6fbd43..6fb0a791f 100644
--- a/dvc/remote/base.py
+++ b/dvc/remote/base.py
@@ -79,6 +79,12 @@ class RemoteBase(object):
     def upload(self, path, path_info, name=None):
         raise NotImplementedError
 
+    def remove(self, path_info):
+        raise NotImplementedError
+
+    def move(self, path_info):
+        raise NotImplementedError
+
     def cache_file_key(self, fname):
         """ Key of a file within the bucket """
         relpath = os.path.relpath(fname, self.project.cache.local.cache_dir)
diff --git a/dvc/remote/local.py b/dvc/remote/local.py
index ff7b97b1b..7b887209f 100644
--- a/dvc/remote/local.py
+++ b/dvc/remote/local.py
@@ -246,6 +246,12 @@ class RemoteLOCAL(RemoteBase):
 
         remove(path_info['path'])
 
+    def move(self, from_info, to_info):
+        if from_info['scheme'] != 'local' or to_info['scheme'] != 'local':
+            raise NotImplementedError
+
+        move(from_info['path'], to_info['path'])
+
     def cache_file_key(self, path):
         relpath = os.path.relpath(os.path.abspath(path), self.project.cache.local.cache_dir)
         return os.path.join(self.prefix, relpath)

Add 'dvc mv'
We have 'add' and 'remove', but lack 'mv'.
diff --git a/tests/test_move.py b/tests/test_move.py
new file mode 100644
index 000000000..9b81b7bb6
--- /dev/null
+++ b/tests/test_move.py
@@ -0,0 +1,41 @@
+import os
+
+from dvc.main import main
+from dvc.exceptions import DvcException
+
+from tests.basic_env import TestDvc
+
+
+class TestMove(TestDvc):
+    def test(self):
+        dst = self.FOO + '1'
+        self.dvc.add(self.FOO)
+        self.dvc.move(self.FOO, dst)
+
+        self.assertFalse(os.path.isfile(self.FOO))
+        self.assertTrue(os.path.isfile(dst))
+
+
+class TestMoveNonExistentFile(TestDvc):
+    def test(self):
+        with self.assertRaises(DvcException) as cx:
+            self.dvc.move('non_existent_file', 'dst')
+
+
+class TestMoveDirectory(TestDvc):
+    def test(self):
+        dst = 'dst'
+        stage_add = self.dvc.add(self.DATA_DIR)
+        self.dvc.move(self.DATA_DIR, dst)
+        self.assertFalse(os.path.exists(self.DATA_DIR))
+        self.assertTrue(os.path.exists(dst))
+
+
+class TestCmdMove(TestDvc):
+    def test(self):
+        stage = self.dvc.add(self.FOO)
+        ret = main(['move', self.FOO, self.FOO + '1'])
+        self.assertEqual(ret, 0)
+
+        ret = main(['move', 'non-existing-file', 'dst'])
+        self.assertNotEqual(ret, 0)

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
altgraph==0.17.4
bcrypt==4.3.0
binaryornot==0.4.4
boto3==1.7.4
botocore==1.10.84
cachetools==4.2.4
certifi==2025.1.31
cffi==1.17.1
chardet==5.2.0
charset-normalizer==3.4.1
colorama==0.4.6
configobj==5.0.9
configparser==7.2.0
coverage==7.8.0
cryptography==44.0.2
decorator==5.2.1
dill==0.2.9
docutils==0.21.2
-e git+https://github.com/iterative/dvc.git@01f700a8bef7926367d317d03fad8f8ad2592f63#egg=dvc
exceptiongroup==1.2.2
execnet==2.1.1
future==0.16.0
gapic-google-cloud-datastore-v1==0.15.3
gapic-google-cloud-error-reporting-v1beta1==0.15.3
gapic-google-cloud-logging-v2==0.91.3
gitdb==4.0.12
GitPython==3.1.44
google-api-core==0.1.4
google-auth==1.35.0
google-cloud==0.32.0
google-cloud-bigquery==0.28.0
google-cloud-bigquery-datatransfer==0.1.1
google-cloud-bigtable==0.28.1
google-cloud-container==0.1.1
google-cloud-core==0.28.1
google-cloud-datastore==1.4.0
google-cloud-dns==0.28.0
google-cloud-error-reporting==0.28.0
google-cloud-firestore==0.28.0
google-cloud-language==1.0.2
google-cloud-logging==1.4.0
google-cloud-monitoring==0.28.1
google-cloud-pubsub==0.30.1
google-cloud-resource-manager==0.28.1
google-cloud-runtimeconfig==0.28.1
google-cloud-spanner==0.29.0
google-cloud-speech==0.30.0
google-cloud-storage==1.6.0
google-cloud-trace==0.17.0
google-cloud-translate==1.3.1
google-cloud-videointelligence==1.0.1
google-cloud-vision==0.29.0
google-crc32c==1.7.1
google-gax==0.15.16
google-resumable-media==2.7.2
googleapis-common-protos==1.69.2
grpc-google-iam-v1==0.11.4
grpcio==1.71.0
httplib2==0.22.0
idna==3.10
iniconfig==2.1.0
jmespath==0.10.0
jsonpath-rw==1.4.0
macholib==1.16.3
nanotime==0.5.2
networkx==3.2.1
ntfsutils==0.1.5
oauth2client==3.0.0
packaging==24.2
paramiko==3.5.1
pefile==2024.8.26
pluggy==1.5.0
ply==3.8
proto-google-cloud-datastore-v1==0.90.4
proto-google-cloud-error-reporting-v1beta1==0.15.3
proto-google-cloud-logging-v2==0.91.3
protobuf==3.20.3
psutil==5.9.8
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.22
PyInstaller==3.3.1
PyNaCl==1.5.0
pyparsing==3.2.3
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.2
reflink==0.2.0
requests==2.32.3
rsa==4.9
s3transfer==0.1.13
schema==0.7.7
six==1.17.0
smmap==5.0.2
tomli==2.2.1
typing_extensions==4.13.0
urllib3==2.3.0
zc.lockfile==3.0.post1

name: dvc
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - altgraph==0.17.4
      - bcrypt==4.3.0
      - binaryornot==0.4.4
      - boto3==1.7.4
      - botocore==1.10.84
      - cachetools==4.2.4
      - certifi==2025.1.31
      - cffi==1.17.1
      - chardet==5.2.0
      - charset-normalizer==3.4.1
      - colorama==0.4.6
      - configobj==5.0.9
      - configparser==7.2.0
      - coverage==7.8.0
      - cryptography==44.0.2
      - decorator==5.2.1
      - dill==0.2.9
      - docutils==0.21.2
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - future==0.16.0
      - gapic-google-cloud-datastore-v1==0.15.3
      - gapic-google-cloud-error-reporting-v1beta1==0.15.3
      - gapic-google-cloud-logging-v2==0.91.3
      - gitdb==4.0.12
      - gitpython==3.1.44
      - google-api-core==0.1.4
      - google-auth==1.35.0
      - google-cloud==0.32.0
      - google-cloud-bigquery==0.28.0
      - google-cloud-bigquery-datatransfer==0.1.1
      - google-cloud-bigtable==0.28.1
      - google-cloud-container==0.1.1
      - google-cloud-core==0.28.1
      - google-cloud-datastore==1.4.0
      - google-cloud-dns==0.28.0
      - google-cloud-error-reporting==0.28.0
      - google-cloud-firestore==0.28.0
      - google-cloud-language==1.0.2
      - google-cloud-logging==1.4.0
      - google-cloud-monitoring==0.28.1
      - google-cloud-pubsub==0.30.1
      - google-cloud-resource-manager==0.28.1
      - google-cloud-runtimeconfig==0.28.1
      - google-cloud-spanner==0.29.0
      - google-cloud-speech==0.30.0
      - google-cloud-storage==1.6.0
      - google-cloud-trace==0.17.0
      - google-cloud-translate==1.3.1
      - google-cloud-videointelligence==1.0.1
      - google-cloud-vision==0.29.0
      - google-crc32c==1.7.1
      - google-gax==0.15.16
      - google-resumable-media==2.7.2
      - googleapis-common-protos==1.69.2
      - grpc-google-iam-v1==0.11.4
      - grpcio==1.71.0
      - httplib2==0.22.0
      - idna==3.10
      - iniconfig==2.1.0
      - jmespath==0.10.0
      - jsonpath-rw==1.4.0
      - macholib==1.16.3
      - nanotime==0.5.2
      - networkx==3.2.1
      - ntfsutils==0.1.5
      - oauth2client==3.0.0
      - packaging==24.2
      - paramiko==3.5.1
      - pefile==2024.8.26
      - pluggy==1.5.0
      - ply==3.8
      - proto-google-cloud-datastore-v1==0.90.4
      - proto-google-cloud-error-reporting-v1beta1==0.15.3
      - proto-google-cloud-logging-v2==0.91.3
      - protobuf==3.20.3
      - psutil==5.9.8
      - pyasn1==0.6.1
      - pyasn1-modules==0.4.2
      - pycparser==2.22
      - pyinstaller==3.3.1
      - pynacl==1.5.0
      - pyparsing==3.2.3
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyyaml==6.0.2
      - reflink==0.2.0
      - requests==2.32.3
      - rsa==4.9
      - s3transfer==0.1.13
      - schema==0.7.7
      - six==1.17.0
      - smmap==5.0.2
      - tomli==2.2.1
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - zc-lockfile==3.0.post1
prefix: /opt/conda/envs/dvc

tests/test_move.py::TestMove::test tests/test_move.py::TestMoveNonExistentFile::test tests/test_move.py::TestMoveDirectory::test tests/test_move.py::TestCmdMove::test
dvc/remote/local.py dvc/project.py dvc/output/local.py dvc/cli.py dvc/remote/base.py dvc/command/move.py dvc/dependency/local.py
dvc/remote/local.py dvc/project.py dvc/output/local.py dvc/cli.py dvc/remote/base.py dvc/command/move.py dvc/dependency/local.py