diff --git a/README.md b/README.md
index 9230fe5..f5d6db7 100644
--- a/README.md
+++ b/README.md
@@ -77,6 +77,14 @@ Availability:
 123456789123456789123456789L  # 123456789123456789123456789
 ```
 
+### Octal literals
+
+Availability:
+- If `pyupgrade` is running in python 2.
+```python
+0755  # 0o755
+```
+
 
 ## Planned features
 
diff --git a/pyupgrade.py b/pyupgrade.py
index d305ad2..cac40ea 100644
--- a/pyupgrade.py
+++ b/pyupgrade.py
@@ -435,6 +435,20 @@ def _fix_long_literals(contents_text):
     return tokens_to_src(tokens)
 
 
+def _fix_octal_literals(contents_text):
+    def _fix_octal(s):
+        if not s.startswith('0') or not s.isdigit() or s == len(s) * '0':
+            return s
+        else:  # pragma: no cover (py2 only)
+            return '0o' + s[1:]
+
+    tokens = src_to_tokens(contents_text)
+    for i, token in enumerate(tokens):
+        if token.name == 'NUMBER':
+            tokens[i] = token._replace(src=_fix_octal(token.src))
+    return tokens_to_src(tokens)
+
+
 def fix_file(filename, args):
     with open(filename, 'rb') as f:
         contents_bytes = f.read()
@@ -450,6 +464,7 @@ def fix_file(filename, args):
     contents_text = _fix_format_literals(contents_text)
     contents_text = _fix_unicode_literals(contents_text, args.py3_only)
     contents_text = _fix_long_literals(contents_text)
+    contents_text = _fix_octal_literals(contents_text)
 
     if contents_text != contents_text_orig:
         print('Rewriting {}'.format(filename))

diff --git a/tests/pyupgrade_test.py b/tests/pyupgrade_test.py
index bbc1a05..712a4e8 100644
--- a/tests/pyupgrade_test.py
+++ b/tests/pyupgrade_test.py
@@ -9,6 +9,7 @@ import pytest
 from pyupgrade import _fix_dictcomps
 from pyupgrade import _fix_format_literals
 from pyupgrade import _fix_long_literals
+from pyupgrade import _fix_octal_literals
 from pyupgrade import _fix_sets
 from pyupgrade import _fix_unicode_literals
 from pyupgrade import _imports_unicode_literals
@@ -309,6 +310,27 @@ def test_long_literals(s, expected):
     assert _fix_long_literals(s) == expected
 
 
+@pytest.mark.parametrize(
+    ('s', 'expected'),
+    (
+        # Any number of zeros is considered a legal token
+        ('0', '0'),
+        ('00', '00'),
+        # Don't modify non octal literals
+        ('1', '1'),
+        ('12345', '12345'),
+        ('1.2345', '1.2345'),
+    ),
+)
+def test_noop_octal_literals(s, expected):
+    assert _fix_octal_literals(s) == expected
+
+
+@pytest.mark.xfail(sys.version_info >= (3,), reason='python2 "feature"')
+def test_fix_octal_literal():
+    assert _fix_octal_literals('0755') == '0o755'
+
+
 def test_main_trivial():
     assert main(()) == 0
 

Upgrade python 2 octal literals
Along the same lines as the long literals
tests/pyupgrade_test.py::test_roundtrip_text[] tests/pyupgrade_test.py::test_roundtrip_text[foo] tests/pyupgrade_test.py::test_roundtrip_text[{}] tests/pyupgrade_test.py::test_roundtrip_text[{0}] tests/pyupgrade_test.py::test_roundtrip_text[{named}] tests/pyupgrade_test.py::test_roundtrip_text[{!r}] tests/pyupgrade_test.py::test_roundtrip_text[{:>5}] tests/pyupgrade_test.py::test_roundtrip_text[{{] tests/pyupgrade_test.py::test_roundtrip_text[}}] tests/pyupgrade_test.py::test_roundtrip_text[{0!s:15}] tests/pyupgrade_test.py::test_intentionally_not_round_trip[{:}-{}] tests/pyupgrade_test.py::test_intentionally_not_round_trip[{0:}-{0}] tests/pyupgrade_test.py::test_intentionally_not_round_trip[{0!r:}-{0!r}] tests/pyupgrade_test.py::test_sets[set()-set()] tests/pyupgrade_test.py::test_sets[set((\n))-set((\n))] tests/pyupgrade_test.py::test_sets[set tests/pyupgrade_test.py::test_sets[set(())-set()] tests/pyupgrade_test.py::test_sets[set([])-set()] tests/pyupgrade_test.py::test_sets[set(( tests/pyupgrade_test.py::test_sets[set([1, tests/pyupgrade_test.py::test_sets[set([(1, tests/pyupgrade_test.py::test_sets[set([((1, tests/pyupgrade_test.py::test_dictcomps[x tests/pyupgrade_test.py::test_dictcomps[dict()-dict()] tests/pyupgrade_test.py::test_dictcomps[(-(] tests/pyupgrade_test.py::test_dictcomps[dict tests/pyupgrade_test.py::test_format_literals['{}'.format(1)-'{}'.format(1)] tests/pyupgrade_test.py::test_format_literals['{'.format(1)-'{'.format(1)] tests/pyupgrade_test.py::test_format_literals['}'.format(1)-'}'.format(1)] tests/pyupgrade_test.py::test_format_literals[x tests/pyupgrade_test.py::test_format_literals['{0}'.format(1)-'{}'.format(1)] tests/pyupgrade_test.py::test_format_literals['''{0}\n{1}\n'''.format(1, tests/pyupgrade_test.py::test_format_literals['{0}' tests/pyupgrade_test.py::test_format_literals[print(\n tests/pyupgrade_test.py::test_format_literals['{0:<{1}}'.format(1, tests/pyupgrade_test.py::test_imports_unicode_literals[import tests/pyupgrade_test.py::test_imports_unicode_literals[from tests/pyupgrade_test.py::test_imports_unicode_literals[x tests/pyupgrade_test.py::test_imports_unicode_literals["""docstring"""\nfrom tests/pyupgrade_test.py::test_unicode_literals[(-False-(] tests/pyupgrade_test.py::test_unicode_literals[u''-False-u''] tests/pyupgrade_test.py::test_unicode_literals[u''-True-''] tests/pyupgrade_test.py::test_unicode_literals[from tests/pyupgrade_test.py::test_unicode_literals["""with tests/pyupgrade_test.py::test_noop_octal_literals[0-0] tests/pyupgrade_test.py::test_noop_octal_literals[00-00] tests/pyupgrade_test.py::test_noop_octal_literals[1-1] tests/pyupgrade_test.py::test_noop_octal_literals[12345-12345] tests/pyupgrade_test.py::test_noop_octal_literals[1.2345-1.2345] tests/pyupgrade_test.py::test_main_trivial tests/pyupgrade_test.py::test_main_noop tests/pyupgrade_test.py::test_main_syntax_error tests/pyupgrade_test.py::test_main_non_utf8_bytes tests/pyupgrade_test.py::test_py3_only_argument_unicode_literals