diff --git a/lib/rdoc/code_object.rb b/lib/rdoc/code_object.rb
index 83997c2580..3b4c37cdfe 100644
--- a/lib/rdoc/code_object.rb
+++ b/lib/rdoc/code_object.rb
@@ -424,4 +424,13 @@ def suppressed?
     @suppressed
   end
 
+  ##
+  # Autolink in cross reference?
+
+  def autolink?
+    RDoc::Options.boolean(@metadata.fetch("autolink", true), "autolink")
+  end
+
+  # Process :autolink: directive and empty it.
+  RDoc::Markup::PreProcess.register("autolink") {""}
 end
diff --git a/lib/rdoc/markup/to_html_crossref.rb b/lib/rdoc/markup/to_html_crossref.rb
index 06fee91a11..16516ae0d6 100644
--- a/lib/rdoc/markup/to_html_crossref.rb
+++ b/lib/rdoc/markup/to_html_crossref.rb
@@ -58,7 +58,7 @@ def init_link_notation_regexp_handlings
   # Creates a link to the reference +name+ if the name exists.  If +text+ is
   # given it is used as the link text, otherwise +name+ is used.
 
-  def cross_reference name, text = nil, code = true, rdoc_ref: false
+  def cross_reference name, text = nil, code = true, rdoc_ref: false, autolink: true
     lookup = name
 
     name = name[1..-1] unless @show_hash if name[0, 1] == '#'
@@ -70,7 +70,7 @@ def cross_reference name, text = nil, code = true, rdoc_ref: false
       text ||= name
     end
 
-    link lookup, text, code, rdoc_ref: rdoc_ref
+    link lookup, text, code, rdoc_ref: rdoc_ref, autolink: autolink
   end
 
   ##
@@ -94,7 +94,7 @@ def handle_regexp_CROSSREF(target)
       return name if name =~ /\A[a-z]*\z/
     end
 
-    cross_reference name, rdoc_ref: false
+    cross_reference name, rdoc_ref: false, autolink: false
   end
 
   ##
@@ -147,7 +147,7 @@ def gen_url url, text
   ##
   # Creates an HTML link to +name+ with the given +text+.
 
-  def link name, text, code = true, rdoc_ref: false
+  def link name, text, code = true, rdoc_ref: false, autolink: true
     if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])?@/
       name = $1
       label = $'
@@ -165,6 +165,7 @@ def link name, text, code = true, rdoc_ref: false
       path = ref ? ref.as_href(@from_path) : +""
 
       if code and RDoc::CodeObject === ref and !(RDoc::TopLevel === ref)
+        return text unless autolink or ref.autolink?
         text = "#{CGI.escapeHTML text}"
       end
 
diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb
index d6c8db2c28..60fc533bd3 100644
--- a/lib/rdoc/options.rb
+++ b/lib/rdoc/options.rb
@@ -1394,4 +1394,15 @@ def self.load_options
     options
   end
 
+  def self.boolean(flag, message = nil)
+    if flag == true or flag == false
+      flag
+    elsif "yes".casecmp(flag) == 0 or "true".casecmp(flag) == 0
+      true
+    elsif "no".casecmp(flag) == 0 or "false".casecmp(flag) == 0
+      false
+    else
+      raise ArgumentError, [message, flag.inspect].compact.join(": ")
+    end
+  end
 end
diff --git a/test/rdoc/test_rdoc_code_object.rb b/test/rdoc/test_rdoc_code_object.rb
index 24e228cce1..2392741381 100644
--- a/test/rdoc/test_rdoc_code_object.rb
+++ b/test/rdoc/test_rdoc_code_object.rb
@@ -437,4 +437,13 @@ def test_suppress_eh
     assert @co.suppressed?
   end
 
+  def test_autolink
+    assert_predicate @c1, :autolink?, "default is true"
+
+    @c1.metadata["autolink"] = "false"
+    assert_not_predicate @c1, :autolink?
+
+    @c1.metadata["autolink"] = "true"
+    assert_predicate @c1, :autolink?
+  end
 end
diff --git a/test/rdoc/test_rdoc_markup_to_html_crossref.rb b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
index 5826f3d095..f88aad318b 100644
--- a/test/rdoc/test_rdoc_markup_to_html_crossref.rb
+++ b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
@@ -47,6 +47,20 @@ def test_convert_CROSSREF_ignored_excluded_words
     assert_equal para("Constant"), result
   end
 
+  def test_convert_CROSSREF_no_autolink
+    @c1.metadata["autolink"] = "false"
+
+    result = @to.convert 'C1'
+    assert_equal para("C1"), result
+
+    result = @to.convert '+C1+'
+    assert_equal para("C1"), result
+
+    # Explicit linking with rdoc-ref is not ignored
+    result = @to.convert 'Constant[rdoc-ref:C1]'
+    assert_equal para("Constant"), result
+  end
+
   def test_convert_CROSSREF_method
     result = @to.convert 'C1#m(foo, bar, baz)'
 
diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
index 9fc6830239..3af529c782 100644
--- a/test/rdoc/test_rdoc_options.rb
+++ b/test/rdoc/test_rdoc_options.rb
@@ -964,6 +964,20 @@ def test_exclude_option_without_default
     assert_not_match exclude, "foo~"
   end
 
+  def test_boolean
+    assert_equal true, RDoc::Options.boolean(true)
+    assert_equal true, RDoc::Options.boolean("true")
+    assert_equal true, RDoc::Options.boolean("yes")
+
+    assert_equal false, RDoc::Options.boolean(false)
+    assert_equal false, RDoc::Options.boolean("false")
+    assert_equal false, RDoc::Options.boolean("no")
+
+    assert_raise(ArgumentError) do
+      RDoc::Options.boolean("unknown")
+    end
+  end
+
   class DummyCoder < Hash
     alias add :[]=
     def tag=(tag)