This is an old post, but all of the existing answers define some new commands and then require additional massaging to get the (2') label to work. A better approach is to "fix" the labeling once and forall so that the referencing works as expected when the enumerate environment is used in the "normal" way:
\begin{enumerate}
\item text1\label{itm:1}.
\item text2\label{itm:2}.
\item[(2')] manually different label\label{itm:2b}.
\item text3\label{itm:3}.
\end{enumerate}
Referencing to \ref{itm:1}\ref{itm:2}\ref{itm:2b}\ref{itm:3}.
As Ambika Vanchinathano says, to do this we need to redefine the value of \@currentlabel whenever \item is given an optional argument. The following lines of code define a new item command, \myItem, that does exactly this (I use the xparse package because it gives a cleaner way of dealing with optional arguments):
\let\realItem\item % save the original item command
\NewDocumentCommand\myItem{ o }{%
\IfNoValueTF{#1}%
{\realItem}% add an item
{\realItem[#1]\def\@currentlabel{#1}}% add an item and update label
}
That is, \myItem uses the original \item command to set the label and it updates \@currentlabel when it is given an optional argument. In practice, we need to wrap these commands inside \makeatletter...\makeatother but the code above is essentially all we need.
We can tell the enumerate environment to use \myItem instead of \item using \setlist:
\setlist[enumerate]{before=\let\item\myItem}% make \item=\myItem
This approach will work without change if you use the hyperref package.
Putting this all together, here is full code. I have put all of the formatting from the MWE into the \setlist command:
\documentclass{article}
\usepackage{xparse}
\let\realItem\item % save a copy of the original item
\makeatletter
\NewDocumentCommand\myItem{ o }{%
\IfNoValueTF{#1}%
{\realItem}% add an item
{\realItem[#1]\def\@currentlabel{#1}}% add an item and update label
}
\makeatother
\usepackage{enumitem}
\setlist[enumerate]{
before=\let\item\myItem, % use \myItem in enumerate
label=\textnormal{(\arabic*)}, % format the label
widest=(2') % set the widest label
}
\begin{document}
\begin{enumerate}
\item text1\label{itm:1}.
\item text2\label{itm:2}.
\item[(2')] manually different label\label{itm:2b}.
\item text3\label{itm:3}.
\end{enumerate}
Referencing to \ref{itm:1}\ref{itm:2}\ref{itm:2b}\ref{itm:3}.
\end{document}
This results in the expected output:

In practice, rather than redefining the enumerate environment to work like this you might want to create a new enumerate-like environment using the \newlist command from the enumitem package.
Actually, I am a little surprised that the enumerate environments do not redefine \@currentlabel like this when \item has an optional argument...
[ ]. – Sigur Jul 06 '15 at 10:21[].\newcommand{\mylabel}[2]{#2\def\@currentlabel{#2}\label{#1}}and\item[\mylabel{itm:2b}{(2')}] manually...– Sigur Jul 06 '15 at 10:25hyperref- a link to(2')with still link to(2). – bers Nov 26 '16 at 17:06